From 74f8bb1062db0fb8db3011653e547bc333845608 Mon Sep 17 00:00:00 2001 From: Simon Burkhardt Date: Wed, 19 Apr 2023 17:49:47 +0200 Subject: [PATCH 1/7] major "refactor" work in progress --- README.md | 60 +- build.sh | 85 - build.tcl | 272 --- build_bitstream_export_sdk.tcl | 45 - download_bitstream.tcl | 27 - download_elf.tcl | 31 - ghdl/compile.bat | 25 + .../skidbuffer-github.vhd | 320 ++- ghdl/skidbuffer.vhd | 110 + ghdl/tb_skid.vhd | 237 +++ ghdl/wave.vcd | 1775 +++++++++++++++++ ghdl/waveform.gtkw | 43 + hw/bd/readme | 5 - hw/hdl/readme | 2 - hw/hdl/sim/readme | 3 - hw/ips/readme | 8 - hw/ips/skidbuffer/component.xml | 397 ---- hw/ips/skidbuffer/xgui/skidbuffer_v1_0.tcl | 40 - hw/xdc/readme | 2 - img/wavedrom.svg | 4 + sdk.tcl | 66 - src/readme | 5 - vivado/readme | 9 - 23 files changed, 2325 insertions(+), 1246 deletions(-) delete mode 100755 build.sh delete mode 100644 build.tcl delete mode 100644 build_bitstream_export_sdk.tcl delete mode 100644 download_bitstream.tcl delete mode 100644 download_elf.tcl create mode 100644 ghdl/compile.bat rename hw/hdl/skidbuffer.vhd => ghdl/skidbuffer-github.vhd (53%) create mode 100644 ghdl/skidbuffer.vhd create mode 100644 ghdl/tb_skid.vhd create mode 100644 ghdl/wave.vcd create mode 100644 ghdl/waveform.gtkw delete mode 100644 hw/bd/readme delete mode 100644 hw/hdl/readme delete mode 100644 hw/hdl/sim/readme delete mode 100644 hw/ips/readme delete mode 100644 hw/ips/skidbuffer/component.xml delete mode 100644 hw/ips/skidbuffer/xgui/skidbuffer_v1_0.tcl delete mode 100644 hw/xdc/readme create mode 100644 img/wavedrom.svg delete mode 100644 sdk.tcl delete mode 100644 src/readme delete mode 100644 vivado/readme diff --git a/README.md b/README.md index 32d9944..7fb0d83 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,22 @@ -# 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. +# Idea -# Module/IP design +![img/wavedrom.svg](img/wavedrom.svg) -Describe here your module interface and protocols. -![Place here a nice picture of your design](my-awesome-module.png) +# Simulation -# How to use this repository +Assuming `ghdl` and `gtkwave` installed on Windows. -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. -In command line, create an empty repository called ** in github and follow these steps to use it as a template: - -``` -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 -``` - -Each directory has instructions related to the kind of file you have to place in them. - -# How to run it - -These scripts are assuming Linux operation system (Ubuntu 18.04) and Vivado 2018.2. - -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* - -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. - -# How to update the scripts - -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: - -``` -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 +```batch +.\compile.bat ``` -Solve any conflict manually and then commit. -# Future work +# Acknowledgements - - update the scripts to Vitis - - support or test with Windows (help required !!! :D ) +https://zipcpu.com/blog/2019/05/22/skidbuffer.html -# Credits -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/compile.bat b/ghdl/compile.bat new file mode 100644 index 0000000..5e93a0a --- /dev/null +++ b/ghdl/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 skidbuffer.vhd +ghdl -a tb_skid.vhd +:: elaborate +ghdl -e skidbuffer +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/hw/hdl/skidbuffer.vhd b/ghdl/skidbuffer-github.vhd similarity index 53% rename from hw/hdl/skidbuffer.vhd rename to ghdl/skidbuffer-github.vhd index 03577e5..aaeb348 100644 --- a/hw/hdl/skidbuffer.vhd +++ b/ghdl/skidbuffer-github.vhd @@ -1,198 +1,122 @@ --- --- 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; +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; \ No newline at end of file diff --git a/ghdl/skidbuffer.vhd b/ghdl/skidbuffer.vhd new file mode 100644 index 0000000..e4c34b2 --- /dev/null +++ b/ghdl/skidbuffer.vhd @@ -0,0 +1,110 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity skidbuffer is + generic ( + DW : integer := 32; + OPT_INREG : 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 arch_imp of skidbuffer is + -- input signals (registered depending on OPT_INREG) + signal reg_data : std_logic_vector(DW-1 downto 0); + signal reg_last : std_logic; + signal reg_valid : std_logic; + signal reg_ready : std_logic; + + -- skid buffer signals from Slave to Master direction + signal skd_data : std_logic_vector(DW-1 downto 0); + signal skd_last : std_logic; + + -- output signals + signal out_data : std_logic_vector(DW-1 downto 0); + signal out_last : std_logic; + signal out_ready : std_logic; + +begin + -- I/O connections assignments + out_ready <= reg_ready; + s_ready_o <= out_ready; + m_valid_o <= reg_valid; + m_data_o <= out_data; + m_last_o <= out_last; + + -- combinatorial multiplexers + -- "output" = "input" when ready==1, otherwise use "buffer content" + out_data <= reg_data when (reg_ready = '1') else skd_data; + out_last <= reg_last when (reg_ready = '1') else skd_last; + + gen_input_register : if OPT_INREG generate + -- registered input signals + p_reg : process (clock) + begin + if rising_edge(clock) then + if reset_n = '0' then + reg_data <= (others => '0'); + reg_last <= '0'; + reg_valid <= '0'; + else + reg_valid <= s_valid_i; + if(out_ready = '0') then + reg_data <= reg_data; + reg_last <= reg_last; + else + reg_data <= s_data_i; + reg_last <= s_last_i; + end if; + end if; + end if; + end process; + end generate; + + -- combinatorial input signals + gen_no_input_register : if not OPT_INREG generate + reg_valid <= s_valid_i; + reg_data <= s_data_i; + reg_last <= s_last_i; + end generate; + + 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; + + -- skid buffer looping output back into register + p_skid_buf : process (clock) + begin + if rising_edge(clock) then + if reset_n = '0' then + skd_data <= (others => '0'); + skd_last <= '0'; + else + skd_data <= out_data; + skd_last <= out_last; + end if; + end if; + end process; + +end arch_imp; diff --git a/ghdl/tb_skid.vhd b/ghdl/tb_skid.vhd new file mode 100644 index 0000000..a317c2f --- /dev/null +++ b/ghdl/tb_skid.vhd @@ -0,0 +1,237 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 03/22/2023 09:03:36 AM +-- Design Name: +-- Module Name: tb_skid - bh +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity tb_skid is + generic + ( + DW : natural := 8; + OPT_INREG : boolean := True + ); +end tb_skid; + +architecture bh of tb_skid is + -- component declaration + component skidbuffer is + generic ( + DW : natural; + OPT_INREG : 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(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 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(DW-1 downto 0); + + signal s_axis_tvalid : std_logic := '0'; + signal s_axis_tdata : std_logic_vector(DW-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(DW-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; + + -- TODO: this is a bug. m_axis is a stimulated signal and not read from the DUT + -- why is this if-statement delayed by 1 clk? it should read from s_axis_tready instead + -- generate counter data when successfully acknowledged 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) = 4 then + s_axis_tdata(DW-1 downto 1) <= (others => '0'); + s_axis_tdata(0) <= '1'; + sim_data(DW-1 downto 1) <= (others => '0'); + sim_data(0) <= '1'; + s_axis_tlast <= '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(DW-1 downto 1) <= (others => '0'); + sim_data(0) <= '1'; + else + sim_data <= std_logic_vector(unsigned(sim_data) + 1); + end if; + s_axis_tlast <= '0'; + 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; + + skidbuffer_inst : skidbuffer + generic map ( + DW => DW, + OPT_INREG => OPT_INREG + ) + 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/wave.vcd b/ghdl/wave.vcd new file mode 100644 index 0000000..ef5cc3f --- /dev/null +++ b/ghdl/wave.vcd @@ -0,0 +1,1775 @@ +$date + Wed Apr 19 17:47:28 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 +$var reg 1 A out_ready $end +$scope module gen_input_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@ +UA +#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@ +0A +#6250000 +1- +10 +#7500000 +0, +0/ +#10000000 +1! +1' +1, +b00000010 . +1/ +13 +1< +1A +#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 ? +#22500000 +0, +0/ +#25000000 +b00000011 # +b00000011 % +b00000010 ) +1, +b00000101 . +1/ +b00000011 4 +b00000010 8 +b00000010 9 +b00000001 = +b00000010 ? +#27500000 +0, +0/ +#30000000 +b00000100 # +b00000100 % +b00000011 ) +1, +b00000110 . +1/ +b00000100 4 +b00000011 8 +b00000011 9 +b00000010 = +b00000011 ? +#32500000 +0, +0/ +#35000000 +0" +b00000001 # +b00000001 % +1& +b00000100 ) +1, +b00000111 . +1/ +12 +b00000001 4 +b00000100 8 +b00000100 9 +b00000011 = +b00000100 ? +#37500000 +0, +0/ +#40000000 +1" +b00000010 # +b00000010 % +0& +b00000001 ) +1* +0+ +1, +b00001000 . +1/ +02 +b00000010 4 +16 +07 +b00000001 8 +b00000001 9 +1: +b00000100 = +b00000001 ? +1@ +#42500000 +0, +0/ +#45000000 +b00000011 # +b00000011 % +0' +1+ +1, +b00001001 . +1/ +03 +b00000011 4 +17 +b00000010 9 +0: +0< +b00000001 = +1> +0A +#47500000 +0, +0/ +#50000000 +1' +b00000010 ) +0* +1, +b00001010 . +1/ +13 +06 +b00000010 8 +1< +b00000010 ? +0@ +1A +#52500000 +0, +0/ +#55000000 +0" +b00000100 # +b00000100 % +b00000011 ) +1, +b00001011 . +1/ +b00000100 4 +b00000011 8 +b00000011 9 +b00000010 = +0> +b00000011 ? +#57500000 +0, +0/ +#60000000 +b00000001 # +b00000001 % +1& +b00000100 ) +0+ +1, +b00001100 . +1/ +12 +b00000001 4 +07 +b00000100 8 +b00000100 9 +b00000011 = +b00000100 ? +#62500000 +0, +0/ +#65000000 +1" +b00000010 # +b00000010 % +0& +0' +1, +b00001101 . +1/ +02 +03 +b00000010 4 +b00000001 9 +1: +0< +b00000100 = +0A +#67500000 +0, +0/ +#70000000 +0" +1+ +1, +b00001110 . +1/ +17 +#72500000 +0, +0/ +#75000000 +1" +1' +b00000001 ) +1* +0+ +1, +b00001111 . +1/ +13 +16 +07 +b00000001 8 +1< +b00000001 ? +1@ +1A +#77500000 +0, +0/ +#80000000 +b00000011 # +b00000011 % +0' +1+ +1, +b00010000 . +1/ +03 +b00000011 4 +17 +b00000010 9 +0: +0< +b00000001 = +1> +0A +#82500000 +0, +0/ +#85000000 +1' +b00000010 ) +0* +1, +b00010001 . +1/ +13 +06 +b00000010 8 +1< +b00000010 ? +0@ +1A +#87500000 +0, +0/ +#90000000 +0! +b00000100 # +b00000100 % +b00000011 ) +1, +b00010010 . +1/ +b00000100 4 +b00000011 8 +b00000011 9 +b00000010 = +0> +b00000011 ? +#92500000 +0, +0/ +#95000000 +0$ +b00000000 % +b00000100 ) +1, +b00010011 . +1/ +01 +b00000000 4 +b00000100 8 +b00000100 9 +b00000011 = +b00000100 ? +#97500000 +0, +0/ +#100000000 +0( +b00000000 ) +1, +b00010100 . +1/ +05 +b00000000 8 +b00000000 9 +0; +b00000100 = +b00000000 ? +#102500000 +0, +0/ +#105000000 +1! +1, +b00010101 . +1/ +b00000000 = +#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 ? +#117500000 +0, +0/ +#120000000 +1! +0$ +b00000000 % +b00000010 ) +1, +b00011000 . +1/ +01 +b00000000 4 +b00000010 8 +b00000010 9 +b00000001 = +b00000010 ? +#122500000 +0, +0/ +#125000000 +b00000011 # +1$ +b00000011 % +0( +b00000000 ) +1, +b00011001 . +1/ +11 +b00000011 4 +05 +b00000000 8 +b00000000 9 +0; +b00000010 = +b00000000 ? +#127500000 +0, +0/ +#130000000 +0! +b00000100 # +b00000100 % +1( +b00000011 ) +1, +b00011010 . +1/ +b00000100 4 +15 +b00000011 8 +b00000011 9 +1; +b00000000 = +b00000011 ? +#132500000 +0, +0/ +#135000000 +0$ +b00000000 % +b00000100 ) +1, +b00011011 . +1/ +01 +b00000000 4 +b00000100 8 +b00000100 9 +b00000011 = +b00000100 ? +#137500000 +0, +0/ +#140000000 +0( +b00000000 ) +1, +b00011100 . +1/ +05 +b00000000 8 +b00000000 9 +0; +b00000100 = +b00000000 ? +#142500000 +0, +0/ +#145000000 +1, +b00011101 . +1/ +b00000000 = +#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/waveform.gtkw b/ghdl/waveform.gtkw new file mode 100644 index 0000000..8e76741 --- /dev/null +++ b/ghdl/waveform.gtkw @@ -0,0 +1,43 @@ +[*] +[*] GTKWave Analyzer v3.3.100 (w)1999-2019 BSI +[*] Wed Apr 19 14:08:18 2023 +[*] +[dumpfile] "C:\Users\simon\Downloads\P9\ghdl-axi-sim\skid\wave.vcd" +[dumpfile_mtime] "Wed Apr 19 13:44:56 2023" +[dumpfile_size] 14757 +[savefile] "C:\Users\simon\Downloads\P9\ghdl-axi-sim\skid\waveform.gtkw" +[timestart] 0 +[size] 1920 1057 +[pos] -1 -1 +*-24.000000 98390000 -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] 314 +@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] +@28 +tb_skid.s_axis_tlast +tb_skid.s_axis_tready +[color] 2 +tb_skid.m_axis_tvalid +@22 +[color] 2 +tb_skid.m_axis_tdata[7:0] +@28 +[color] 2 +tb_skid.m_axis_tlast +[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/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/wavedrom.svg b/img/wavedrom.svg new file mode 100644 index 0000000..0abe8fd --- /dev/null +++ b/img/wavedrom.svg @@ -0,0 +1,4 @@ + + + +2345678910111213141516171819202122232425262728aclks_valid 🡲s_data 🡲1234123412341234reg_data1234123412341234s_ready 🡠m_valid 🡲m_data 🡲1234123412341234m_ready 🡠 \ 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 - From f6741fb82eb302c95d0aada3302ad2abdb8ea391 Mon Sep 17 00:00:00 2001 From: Simon Burkhardt Date: Thu, 20 Apr 2023 17:40:04 +0200 Subject: [PATCH 2/7] i am doing something --- ghdl/skidbuffer - delay.vhd | 110 ++++++++++++++++ ghdl/skidbuffer - nodelay.vhd | 88 +++++++++++++ ghdl/skidbuffer.vhd | 125 +++++++++--------- ghdl/tb_skid.vhd | 37 +++--- ghdl/wave.vcd | 242 ++++++++++++++++------------------ 5 files changed, 401 insertions(+), 201 deletions(-) create mode 100644 ghdl/skidbuffer - delay.vhd create mode 100644 ghdl/skidbuffer - nodelay.vhd diff --git a/ghdl/skidbuffer - delay.vhd b/ghdl/skidbuffer - delay.vhd new file mode 100644 index 0000000..e4c34b2 --- /dev/null +++ b/ghdl/skidbuffer - delay.vhd @@ -0,0 +1,110 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity skidbuffer is + generic ( + DW : integer := 32; + OPT_INREG : 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 arch_imp of skidbuffer is + -- input signals (registered depending on OPT_INREG) + signal reg_data : std_logic_vector(DW-1 downto 0); + signal reg_last : std_logic; + signal reg_valid : std_logic; + signal reg_ready : std_logic; + + -- skid buffer signals from Slave to Master direction + signal skd_data : std_logic_vector(DW-1 downto 0); + signal skd_last : std_logic; + + -- output signals + signal out_data : std_logic_vector(DW-1 downto 0); + signal out_last : std_logic; + signal out_ready : std_logic; + +begin + -- I/O connections assignments + out_ready <= reg_ready; + s_ready_o <= out_ready; + m_valid_o <= reg_valid; + m_data_o <= out_data; + m_last_o <= out_last; + + -- combinatorial multiplexers + -- "output" = "input" when ready==1, otherwise use "buffer content" + out_data <= reg_data when (reg_ready = '1') else skd_data; + out_last <= reg_last when (reg_ready = '1') else skd_last; + + gen_input_register : if OPT_INREG generate + -- registered input signals + p_reg : process (clock) + begin + if rising_edge(clock) then + if reset_n = '0' then + reg_data <= (others => '0'); + reg_last <= '0'; + reg_valid <= '0'; + else + reg_valid <= s_valid_i; + if(out_ready = '0') then + reg_data <= reg_data; + reg_last <= reg_last; + else + reg_data <= s_data_i; + reg_last <= s_last_i; + end if; + end if; + end if; + end process; + end generate; + + -- combinatorial input signals + gen_no_input_register : if not OPT_INREG generate + reg_valid <= s_valid_i; + reg_data <= s_data_i; + reg_last <= s_last_i; + end generate; + + 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; + + -- skid buffer looping output back into register + p_skid_buf : process (clock) + begin + if rising_edge(clock) then + if reset_n = '0' then + skd_data <= (others => '0'); + skd_last <= '0'; + else + skd_data <= out_data; + skd_last <= out_last; + end if; + end if; + end process; + +end arch_imp; diff --git a/ghdl/skidbuffer - nodelay.vhd b/ghdl/skidbuffer - nodelay.vhd new file mode 100644 index 0000000..f7292c5 --- /dev/null +++ b/ghdl/skidbuffer - nodelay.vhd @@ -0,0 +1,88 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity skidbuffer is + generic ( + DW : integer := 32; + OPT_INREG : 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 arch_imp of skidbuffer is + -- input signals (registered depending on OPT_INREG) + signal reg_data : std_logic_vector(DW-1 downto 0); + signal reg_last : std_logic; + signal reg_valid : std_logic; + signal reg_ready : std_logic; + + -- skid buffer signals from Slave to Master direction + signal skd_data : std_logic_vector(DW-1 downto 0); + signal skd_last : std_logic; + + -- output signals + signal out_data : std_logic_vector(DW-1 downto 0); + signal out_last : std_logic; + signal out_ready : std_logic; + +begin + -- I/O connections assignments + m_valid_o <= reg_valid; + reg_valid <= s_valid_i; + + out_ready <= reg_ready; + s_ready_o <= out_ready; + + m_data_o <= out_data; + m_last_o <= out_last; + + -- combinatorial multiplexers + -- "output" = "input" when ready==1, otherwise use "buffer content" + out_data <= s_data_i when (reg_ready = '1') else skd_data; + out_last <= s_last_i when (reg_ready = '1') else skd_last; + + 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; + + -- skid buffer looping output back into register + p_skid_buf : process (clock) + begin + if rising_edge(clock) then + if reset_n = '0' then + skd_data <= (others => '0'); + skd_last <= '0'; + else + 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; + end if; + end if; + end process; + +end arch_imp; diff --git a/ghdl/skidbuffer.vhd b/ghdl/skidbuffer.vhd index e4c34b2..8ae32fa 100644 --- a/ghdl/skidbuffer.vhd +++ b/ghdl/skidbuffer.vhd @@ -4,8 +4,8 @@ use ieee.numeric_std.all; entity skidbuffer is generic ( - DW : integer := 32; - OPT_INREG : boolean := True + DATA_WIDTH : integer := 32; + OPT_DATA_REG : boolean := True ); port ( clock : in std_logic; @@ -14,74 +14,39 @@ entity skidbuffer is 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); + 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(DW - 1 downto 0) + m_data_o : out std_logic_vector(DATA_WIDTH - 1 downto 0) ); end skidbuffer; architecture arch_imp of skidbuffer is - -- input signals (registered depending on OPT_INREG) - signal reg_data : std_logic_vector(DW-1 downto 0); + -- input signals (registered depending on OPT_DATA_REG) + 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 from Slave to Master direction - signal skd_data : std_logic_vector(DW-1 downto 0); - signal skd_last : std_logic; - -- output signals - signal out_data : std_logic_vector(DW-1 downto 0); + signal out_data : std_logic_vector(DATA_WIDTH-1 downto 0); signal out_last : std_logic; signal out_ready : std_logic; + signal out_valid : std_logic; begin -- I/O connections assignments - out_ready <= reg_ready; - s_ready_o <= out_ready; - m_valid_o <= reg_valid; + m_valid_o <= out_valid; m_data_o <= out_data; m_last_o <= out_last; + s_ready_o <= out_ready; - -- combinatorial multiplexers - -- "output" = "input" when ready==1, otherwise use "buffer content" - out_data <= reg_data when (reg_ready = '1') else skd_data; - out_last <= reg_last when (reg_ready = '1') else skd_last; - - gen_input_register : if OPT_INREG generate - -- registered input signals - p_reg : process (clock) - begin - if rising_edge(clock) then - if reset_n = '0' then - reg_data <= (others => '0'); - reg_last <= '0'; - reg_valid <= '0'; - else - reg_valid <= s_valid_i; - if(out_ready = '0') then - reg_data <= reg_data; - reg_last <= reg_last; - else - reg_data <= s_data_i; - reg_last <= s_last_i; - end if; - end if; - end if; - end process; - end generate; - - -- combinatorial input signals - gen_no_input_register : if not OPT_INREG generate - reg_valid <= s_valid_i; - reg_data <= s_data_i; - reg_last <= s_last_i; - end generate; + out_ready <= reg_ready; + out_valid <= reg_valid; + -- ready is always registered p_reg_ready : process(clock) begin if rising_edge(clock) then @@ -93,18 +58,58 @@ begin end if; end process; - -- skid buffer looping output back into register - p_skid_buf : process (clock) - begin - if rising_edge(clock) then - if reset_n = '0' then - skd_data <= (others => '0'); - skd_last <= '0'; - else - skd_data <= out_data; - skd_last <= out_last; + -- combinatorial output signals + gen_no_register : if not OPT_DATA_REG generate + + + p_reg : process (clock) + begin + if rising_edge(clock) then + if reset_n = '0' then + reg_data <= (others => '0'); + reg_last <= '0'; + else + if m_ready_i = '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 if; - end process; + end process; + + -- output multiplexer + out_data <= reg_data when (reg_ready = '1') else s_data_i; + out_last <= reg_last when (reg_ready = '1') else s_last_i; + + reg_valid <= s_valid_i; -- valid is not registered + end generate; + + 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'; + reg_valid <= '0'; + else + reg_valid <= s_valid_i; + if(m_ready_i = '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; end arch_imp; diff --git a/ghdl/tb_skid.vhd b/ghdl/tb_skid.vhd index a317c2f..51bdc48 100644 --- a/ghdl/tb_skid.vhd +++ b/ghdl/tb_skid.vhd @@ -35,8 +35,8 @@ use ieee.numeric_std.all; entity tb_skid is generic ( - DW : natural := 8; - OPT_INREG : boolean := True + DATA_WIDTH : natural := 8; + OPT_DATA_REG : boolean := False ); end tb_skid; @@ -44,8 +44,8 @@ architecture bh of tb_skid is -- component declaration component skidbuffer is generic ( - DW : natural; - OPT_INREG : boolean); + DATA_WIDTH : natural; + OPT_DATA_REG : boolean); port ( clock : in std_logic; reset_n : in std_logic; @@ -53,27 +53,27 @@ architecture bh of tb_skid is 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); + 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(DW - 1 downto 0)); + 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(DW-1 downto 0); + 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(DW-1 downto 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(DW-1 downto 0); + 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'; @@ -178,12 +178,18 @@ begin 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 - s_axis_tdata(DW-1 downto 1) <= (others => '0'); + -- restart counter at "1" + s_axis_tdata(DATA_WIDTH-1 downto 1) <= (others => '0'); s_axis_tdata(0) <= '1'; - sim_data(DW-1 downto 1) <= (others => '0'); + sim_data(DATA_WIDTH-1 downto 1) <= (others => '0'); sim_data(0) <= '1'; - s_axis_tlast <= '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); @@ -192,12 +198,11 @@ begin end if; if unsigned(sim_data) = 4 then - sim_data(DW-1 downto 1) <= (others => '0'); + 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; - s_axis_tlast <= '0'; end if; else s_axis_tdata <= s_axis_tdata; @@ -216,8 +221,8 @@ begin skidbuffer_inst : skidbuffer generic map ( - DW => DW, - OPT_INREG => OPT_INREG + DATA_WIDTH => DATA_WIDTH, + OPT_DATA_REG => OPT_DATA_REG ) port map ( clock => clk, diff --git a/ghdl/wave.vcd b/ghdl/wave.vcd index ef5cc3f..12007d2 100644 --- a/ghdl/wave.vcd +++ b/ghdl/wave.vcd @@ -1,5 +1,5 @@ $date - Wed Apr 19 17:47:28 2023 + Thu Apr 20 17:19:58 2023 $end $version GHDL v0 @@ -43,12 +43,11 @@ $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 -$var reg 1 A out_ready $end -$scope module gen_input_register $end +$var reg 8 = out_data[7:0] $end +$var reg 1 > out_last $end +$var reg 1 ? out_ready $end +$var reg 1 @ out_valid $end +$scope module gen_no_register $end $upscope $end $upscope $end $upscope $end @@ -61,7 +60,7 @@ bUUUUUUUU # bUUUUUUUU % U& U' -U( +0( bUUUUUUUU ) U* 0+ @@ -74,19 +73,18 @@ b00000000 . U2 U3 bUUUUUUUU 4 -U5 +05 U6 07 bUUUUUUUU 8 bUUUUUUUU 9 U: -U; +0; U< bUUUUUUUU = U> -bUUUUUUUU ? -U@ -UA +U? +0@ #2500000 0, 0/ @@ -95,7 +93,6 @@ b00000000 # b00000000 % 0& 0' -0( b00000000 ) 0* 1+ @@ -105,19 +102,15 @@ b00000001 . 02 03 b00000000 4 -05 06 17 b00000000 8 b00000000 9 0: -0; 0< b00000000 = 0> -b00000000 ? -0@ -0A +0? #6250000 1- 10 @@ -132,7 +125,7 @@ b00000010 . 1/ 13 1< -1A +1? #12500000 0, 0/ @@ -140,28 +133,29 @@ b00000010 . b00000001 # 1$ b00000001 % +1( 1, b00000011 . 1/ 11 b00000001 4 +15 +1; +1@ #17500000 0, 0/ #20000000 b00000010 # b00000010 % -1( b00000001 ) 1, b00000100 . 1/ b00000010 4 -15 b00000001 8 b00000001 9 -1; -b00000001 ? +b00000001 = #22500000 0, 0/ @@ -175,23 +169,23 @@ b00000101 . b00000011 4 b00000010 8 b00000010 9 -b00000001 = -b00000010 ? +b00000010 = #27500000 0, 0/ #30000000 b00000100 # b00000100 % +1& b00000011 ) 1, b00000110 . 1/ +12 b00000100 4 b00000011 8 b00000011 9 -b00000010 = -b00000011 ? +b00000011 = #32500000 0, 0/ @@ -199,17 +193,20 @@ b00000011 ? 0" b00000001 # b00000001 % -1& +0& b00000100 ) +1* 1, b00000111 . 1/ -12 +02 b00000001 4 +16 b00000100 8 b00000100 9 -b00000011 = -b00000100 ? +1: +b00000100 = +1> #37500000 0, 0/ @@ -217,23 +214,20 @@ b00000100 ? 1" b00000010 # b00000010 % -0& b00000001 ) -1* +0* 0+ 1, b00001000 . 1/ -02 b00000010 4 -16 +06 07 b00000001 8 b00000001 9 -1: -b00000100 = -b00000001 ? -1@ +0: +b00000001 = +0> #42500000 0, 0/ @@ -241,6 +235,7 @@ b00000001 ? b00000011 # b00000011 % 0' +b00000011 ) 1+ 1, b00001001 . @@ -248,29 +243,22 @@ b00001001 . 03 b00000011 4 17 -b00000010 9 -0: +b00000011 8 0< -b00000001 = -1> -0A +b00000011 = +0? #47500000 0, 0/ #50000000 1' -b00000010 ) -0* 1, b00001010 . 1/ 13 -06 -b00000010 8 +b00000011 9 1< -b00000010 ? -0@ -1A +1? #52500000 0, 0/ @@ -278,35 +266,34 @@ b00000010 ? 0" b00000100 # b00000100 % -b00000011 ) +1& 1, b00001011 . 1/ +12 b00000100 4 -b00000011 8 -b00000011 9 -b00000010 = -0> -b00000011 ? #57500000 0, 0/ #60000000 b00000001 # b00000001 % -1& +0& b00000100 ) +1* 0+ 1, b00001100 . 1/ -12 +02 b00000001 4 +16 07 b00000100 8 b00000100 9 -b00000011 = -b00000100 ? +1: +b00000100 = +1> #62500000 0, 0/ @@ -314,19 +301,20 @@ b00000100 ? 1" b00000010 # b00000010 % -0& 0' +b00000010 ) +0* 1, b00001101 . 1/ -02 03 b00000010 4 -b00000001 9 -1: +06 +b00000010 8 0< -b00000100 = -0A +b00000010 = +0> +0? #67500000 0, 0/ @@ -343,20 +331,16 @@ b00001110 . #75000000 1" 1' -b00000001 ) -1* 0+ 1, b00001111 . 1/ 13 -16 07 -b00000001 8 +b00000010 9 +0: 1< -b00000001 ? -1@ -1A +1? #77500000 0, 0/ @@ -364,6 +348,7 @@ b00000001 ? b00000011 # b00000011 % 0' +b00000011 ) 1+ 1, b00010000 . @@ -371,29 +356,22 @@ b00010000 . 03 b00000011 4 17 -b00000010 9 -0: +b00000011 8 0< -b00000001 = -1> -0A +b00000011 = +0? #82500000 0, 0/ #85000000 1' -b00000010 ) -0* 1, b00010001 . 1/ 13 -06 -b00000010 8 +b00000011 9 1< -b00000010 ? -0@ -1A +1? #87500000 0, 0/ @@ -401,47 +379,52 @@ b00000010 ? 0! b00000100 # b00000100 % -b00000011 ) +1& 1, b00010010 . 1/ +12 b00000100 4 -b00000011 8 -b00000011 9 -b00000010 = -0> -b00000011 ? #92500000 0, 0/ #95000000 0$ b00000000 % +0& +0( b00000100 ) +1* 1, b00010011 . 1/ 01 +02 b00000000 4 +05 +16 b00000100 8 b00000100 9 -b00000011 = -b00000100 ? +1: +0; +b00000100 = +1> +0@ #97500000 0, 0/ #100000000 -0( b00000000 ) +0* 1, b00010100 . 1/ -05 +06 b00000000 8 b00000000 9 -0; -b00000100 = -b00000000 ? +0: +b00000000 = +0> #102500000 0, 0/ @@ -450,7 +433,6 @@ b00000000 ? 1, b00010101 . 1/ -b00000000 = #107500000 0, 0/ @@ -458,11 +440,15 @@ b00000000 = b00000001 # 1$ b00000001 % +1( 1, b00010110 . 1/ 11 b00000001 4 +15 +1; +1@ #112500000 0, 0/ @@ -470,17 +456,14 @@ b00000001 4 0! b00000010 # b00000010 % -1( b00000001 ) 1, b00010111 . 1/ b00000010 4 -15 b00000001 8 b00000001 9 -1; -b00000001 ? +b00000001 = #117500000 0, 0/ @@ -488,16 +471,19 @@ b00000001 ? 1! 0$ b00000000 % +0( b00000010 ) 1, b00011000 . 1/ 01 b00000000 4 +05 b00000010 8 b00000010 9 -b00000001 = -b00000010 ? +0; +b00000010 = +0@ #122500000 0, 0/ @@ -505,19 +491,19 @@ b00000010 ? b00000011 # 1$ b00000011 % -0( +1( b00000000 ) 1, b00011001 . 1/ 11 b00000011 4 -05 +15 b00000000 8 b00000000 9 -0; -b00000010 = -b00000000 ? +1; +b00000000 = +1@ #127500000 0, 0/ @@ -525,49 +511,56 @@ b00000000 ? 0! b00000100 # b00000100 % -1( +1& b00000011 ) 1, b00011010 . 1/ +12 b00000100 4 -15 b00000011 8 b00000011 9 -1; -b00000000 = -b00000011 ? +b00000011 = #132500000 0, 0/ #135000000 0$ b00000000 % +0& +0( b00000100 ) +1* 1, b00011011 . 1/ 01 +02 b00000000 4 +05 +16 b00000100 8 b00000100 9 -b00000011 = -b00000100 ? +1: +0; +b00000100 = +1> +0@ #137500000 0, 0/ #140000000 -0( b00000000 ) +0* 1, b00011100 . 1/ -05 +06 b00000000 8 b00000000 9 -0; -b00000100 = -b00000000 ? +0: +b00000000 = +0> #142500000 0, 0/ @@ -575,7 +568,6 @@ b00000000 ? 1, b00011101 . 1/ -b00000000 = #147500000 0, 0/ From 6fdea0d4a6b2466e031f17dcae201baa2dcc6171 Mon Sep 17 00:00:00 2001 From: Simon Burkhardt Date: Fri, 21 Apr 2023 08:54:50 +0200 Subject: [PATCH 3/7] passthrough and outreg versions working --- README.md | 36 ++++- ghdl/skidbuffer - delay.vhd | 110 -------------- ghdl/skidbuffer - nodelay.vhd | 88 ----------- ghdl/skidbuffer-github.vhd | 122 --------------- ghdl/skidbuffer.vhd | 76 +++++++--- ghdl/tb_skid.vhd | 47 +++--- ghdl/wave.vcd | 140 +++++++++++------- ghdl/waveform.gtkw | 22 +-- img/gtkwave_fullreg.png | Bin 0 -> 17668 bytes img/gtkwave_passthru.png | Bin 0 -> 17218 bytes img/skidbuf_fullreg.png | Bin 0 -> 38936 bytes img/skidbuf_fullreg.wavedrom.json | 20 +++ img/skidbuf_fullreg_wave.svg | 4 + img/skidbuf_passthru.png | Bin 0 -> 37832 bytes img/skidbuf_passthru.wavedrom.json | 20 +++ ...wavedrom.svg => skidbuf_passthru_wave.svg} | 2 +- img/skidbuffer-concepts.drawio | 1 + 17 files changed, 254 insertions(+), 434 deletions(-) delete mode 100644 ghdl/skidbuffer - delay.vhd delete mode 100644 ghdl/skidbuffer - nodelay.vhd delete mode 100644 ghdl/skidbuffer-github.vhd create mode 100644 img/gtkwave_fullreg.png create mode 100644 img/gtkwave_passthru.png create mode 100644 img/skidbuf_fullreg.png create mode 100644 img/skidbuf_fullreg.wavedrom.json create mode 100644 img/skidbuf_fullreg_wave.svg create mode 100644 img/skidbuf_passthru.png create mode 100644 img/skidbuf_passthru.wavedrom.json rename img/{wavedrom.svg => skidbuf_passthru_wave.svg} (57%) create mode 100644 img/skidbuffer-concepts.drawio diff --git a/README.md b/README.md index 7fb0d83..9181ebd 100644 --- a/README.md +++ b/README.md @@ -2,21 +2,53 @@ # Idea -![img/wavedrom.svg](img/wavedrom.svg) +## Passthrough Skid Buffer +Only the reply signal from downstream slave to upstream master (`tready`) is pipelined. + +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. + +### Schematic +![img/skidbuf_passthru.png](img/skidbuf_passthru.png) + +### Waveform +![img/skidbuf_passthru_wave.svg](img/skidbuf_passthru_wave.svg) +![img/gtkwave_passthru.png](img/gtkwave_passthru.png) + +## Fully Pipelined Skid Buffer + +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. + +### Schematic +![img/skidbuf_fullreg.png](img/skidbuf_fullreg.png) + +### 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 ``` - # 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. + +https://www.itdev.co.uk/blog/pipelining-axi-buses-registered-ready-signals + + diff --git a/ghdl/skidbuffer - delay.vhd b/ghdl/skidbuffer - delay.vhd deleted file mode 100644 index e4c34b2..0000000 --- a/ghdl/skidbuffer - delay.vhd +++ /dev/null @@ -1,110 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -entity skidbuffer is - generic ( - DW : integer := 32; - OPT_INREG : 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 arch_imp of skidbuffer is - -- input signals (registered depending on OPT_INREG) - signal reg_data : std_logic_vector(DW-1 downto 0); - signal reg_last : std_logic; - signal reg_valid : std_logic; - signal reg_ready : std_logic; - - -- skid buffer signals from Slave to Master direction - signal skd_data : std_logic_vector(DW-1 downto 0); - signal skd_last : std_logic; - - -- output signals - signal out_data : std_logic_vector(DW-1 downto 0); - signal out_last : std_logic; - signal out_ready : std_logic; - -begin - -- I/O connections assignments - out_ready <= reg_ready; - s_ready_o <= out_ready; - m_valid_o <= reg_valid; - m_data_o <= out_data; - m_last_o <= out_last; - - -- combinatorial multiplexers - -- "output" = "input" when ready==1, otherwise use "buffer content" - out_data <= reg_data when (reg_ready = '1') else skd_data; - out_last <= reg_last when (reg_ready = '1') else skd_last; - - gen_input_register : if OPT_INREG generate - -- registered input signals - p_reg : process (clock) - begin - if rising_edge(clock) then - if reset_n = '0' then - reg_data <= (others => '0'); - reg_last <= '0'; - reg_valid <= '0'; - else - reg_valid <= s_valid_i; - if(out_ready = '0') then - reg_data <= reg_data; - reg_last <= reg_last; - else - reg_data <= s_data_i; - reg_last <= s_last_i; - end if; - end if; - end if; - end process; - end generate; - - -- combinatorial input signals - gen_no_input_register : if not OPT_INREG generate - reg_valid <= s_valid_i; - reg_data <= s_data_i; - reg_last <= s_last_i; - end generate; - - 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; - - -- skid buffer looping output back into register - p_skid_buf : process (clock) - begin - if rising_edge(clock) then - if reset_n = '0' then - skd_data <= (others => '0'); - skd_last <= '0'; - else - skd_data <= out_data; - skd_last <= out_last; - end if; - end if; - end process; - -end arch_imp; diff --git a/ghdl/skidbuffer - nodelay.vhd b/ghdl/skidbuffer - nodelay.vhd deleted file mode 100644 index f7292c5..0000000 --- a/ghdl/skidbuffer - nodelay.vhd +++ /dev/null @@ -1,88 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -entity skidbuffer is - generic ( - DW : integer := 32; - OPT_INREG : 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 arch_imp of skidbuffer is - -- input signals (registered depending on OPT_INREG) - signal reg_data : std_logic_vector(DW-1 downto 0); - signal reg_last : std_logic; - signal reg_valid : std_logic; - signal reg_ready : std_logic; - - -- skid buffer signals from Slave to Master direction - signal skd_data : std_logic_vector(DW-1 downto 0); - signal skd_last : std_logic; - - -- output signals - signal out_data : std_logic_vector(DW-1 downto 0); - signal out_last : std_logic; - signal out_ready : std_logic; - -begin - -- I/O connections assignments - m_valid_o <= reg_valid; - reg_valid <= s_valid_i; - - out_ready <= reg_ready; - s_ready_o <= out_ready; - - m_data_o <= out_data; - m_last_o <= out_last; - - -- combinatorial multiplexers - -- "output" = "input" when ready==1, otherwise use "buffer content" - out_data <= s_data_i when (reg_ready = '1') else skd_data; - out_last <= s_last_i when (reg_ready = '1') else skd_last; - - 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; - - -- skid buffer looping output back into register - p_skid_buf : process (clock) - begin - if rising_edge(clock) then - if reset_n = '0' then - skd_data <= (others => '0'); - skd_last <= '0'; - else - 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; - end if; - end if; - end process; - -end arch_imp; diff --git a/ghdl/skidbuffer-github.vhd b/ghdl/skidbuffer-github.vhd deleted file mode 100644 index aaeb348..0000000 --- a/ghdl/skidbuffer-github.vhd +++ /dev/null @@ -1,122 +0,0 @@ -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; \ No newline at end of file diff --git a/ghdl/skidbuffer.vhd b/ghdl/skidbuffer.vhd index 8ae32fa..f71abcf 100644 --- a/ghdl/skidbuffer.vhd +++ b/ghdl/skidbuffer.vhd @@ -1,3 +1,22 @@ +---------------------------------------------------------------------------------- +-- 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; @@ -24,27 +43,26 @@ entity skidbuffer is end skidbuffer; architecture arch_imp of skidbuffer is - -- input signals (registered depending on OPT_DATA_REG) + -- 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; - -- output signals + -- 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; - signal out_ready : std_logic; - signal out_valid : std_logic; begin -- I/O connections assignments - m_valid_o <= out_valid; + m_valid_o <= reg_valid; + s_ready_o <= reg_ready; m_data_o <= out_data; m_last_o <= out_last; - s_ready_o <= out_ready; - - out_ready <= reg_ready; - out_valid <= reg_valid; -- ready is always registered p_reg_ready : process(clock) @@ -58,9 +76,12 @@ begin end if; end process; - -- combinatorial output signals +-- 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 @@ -69,7 +90,7 @@ begin reg_data <= (others => '0'); reg_last <= '0'; else - if m_ready_i = '1' then + if reg_ready = '1' then reg_data <= s_data_i; reg_last <= s_last_i; else @@ -80,13 +101,9 @@ begin end if; end process; - -- output multiplexer - out_data <= reg_data when (reg_ready = '1') else s_data_i; - out_last <= reg_last when (reg_ready = '1') else s_last_i; - - reg_valid <= s_valid_i; -- valid is not registered end generate; +-- FULLY REGISTERED OUTPUT ----------------------------------------------------- gen_data_register : if OPT_DATA_REG generate out_data <= reg_data; out_last <= reg_last; @@ -97,15 +114,30 @@ begin 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(m_ready_i = '1') then - reg_data <= s_data_i; - reg_last <= s_last_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 - reg_data <= reg_data; - reg_last <= reg_last; + 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; diff --git a/ghdl/tb_skid.vhd b/ghdl/tb_skid.vhd index 51bdc48..6dd7a94 100644 --- a/ghdl/tb_skid.vhd +++ b/ghdl/tb_skid.vhd @@ -1,16 +1,16 @@ ---------------------------------------------------------------------------------- --- Company: --- Engineer: +-- Company: +-- Engineer: simon.burkhardt -- --- Create Date: 03/22/2023 09:03:36 AM --- Design Name: --- Module Name: tb_skid - bh --- Project Name: +-- Create Date: 2023-04-21 +-- Design Name: skid buffer testbench +-- Module Name: tb_skid - bh +-- Project Name: -- Target Devices: --- Tool Versions: --- Description: +-- Tool Versions: GHDL 0.37 +-- Description: -- --- Dependencies: +-- Dependencies: -- -- Revision: -- Revision 0.01 - File Created @@ -18,30 +18,34 @@ -- ---------------------------------------------------------------------------------- - library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; --- Uncomment the following library declaration if using --- arithmetic functions with Signed or Unsigned values ---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. --- Uncomment the following library declaration if instantiating --- any Xilinx leaf cells in this code. ---library UNISIM; ---use UNISIM.VComponents.all; +-- 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 := False + OPT_DATA_REG : boolean := True ); end tb_skid; architecture bh of tb_skid is - -- component declaration + -- DUT component declaration component skidbuffer is generic ( DATA_WIDTH : natural; @@ -165,9 +169,7 @@ begin end if; end process; - -- TODO: this is a bug. m_axis is a stimulated signal and not read from the DUT - -- why is this if-statement delayed by 1 clk? it should read from s_axis_tready instead - -- generate counter data when successfully acknowledged by slave + -- generate counter data when successfully acknowledged (tready) by slave p_stimuli_tdata : process(clk) begin if rising_edge(clk) then @@ -219,6 +221,7 @@ begin end if; end process; +-- DUT instance and connections skidbuffer_inst : skidbuffer generic map ( DATA_WIDTH => DATA_WIDTH, diff --git a/ghdl/wave.vcd b/ghdl/wave.vcd index 12007d2..cce1d8d 100644 --- a/ghdl/wave.vcd +++ b/ghdl/wave.vcd @@ -1,5 +1,5 @@ $date - Thu Apr 20 17:19:58 2023 + Fri Apr 21 08:48:36 2023 $end $version GHDL v0 @@ -43,11 +43,11 @@ $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 = out_data[7:0] $end -$var reg 1 > out_last $end -$var reg 1 ? out_ready $end -$var reg 1 @ out_valid $end -$scope module gen_no_register $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 @@ -60,7 +60,7 @@ bUUUUUUUU # bUUUUUUUU % U& U' -0( +U( bUUUUUUUU ) U* 0+ @@ -73,18 +73,18 @@ b00000000 . U2 U3 bUUUUUUUU 4 -05 +U5 U6 07 bUUUUUUUU 8 bUUUUUUUU 9 U: -0; +U; U< bUUUUUUUU = U> -U? -0@ +bUUUUUUUU ? +U@ #2500000 0, 0/ @@ -93,6 +93,7 @@ b00000000 # b00000000 % 0& 0' +0( b00000000 ) 0* 1+ @@ -102,15 +103,18 @@ b00000001 . 02 03 b00000000 4 +05 06 17 b00000000 8 b00000000 9 0: +0; 0< b00000000 = 0> -0? +b00000000 ? +0@ #6250000 1- 10 @@ -125,7 +129,6 @@ b00000010 . 1/ 13 1< -1? #12500000 0, 0/ @@ -133,29 +136,29 @@ b00000010 . b00000001 # 1$ b00000001 % -1( 1, b00000011 . 1/ 11 b00000001 4 -15 -1; -1@ #17500000 0, 0/ #20000000 b00000010 # b00000010 % +1( b00000001 ) 1, b00000100 . 1/ b00000010 4 +15 b00000001 8 b00000001 9 +1; b00000001 = +b00000001 ? #22500000 0, 0/ @@ -170,6 +173,7 @@ b00000011 4 b00000010 8 b00000010 9 b00000010 = +b00000010 ? #27500000 0, 0/ @@ -186,6 +190,7 @@ b00000100 4 b00000011 8 b00000011 9 b00000011 = +b00000011 ? #32500000 0, 0/ @@ -207,6 +212,8 @@ b00000100 9 1: b00000100 = 1> +b00000100 ? +1@ #37500000 0, 0/ @@ -228,6 +235,8 @@ b00000001 9 0: b00000001 = 0> +b00000001 ? +0@ #42500000 0, 0/ @@ -235,7 +244,6 @@ b00000001 = b00000011 # b00000011 % 0' -b00000011 ) 1+ 1, b00001001 . @@ -243,22 +251,22 @@ b00001001 . 03 b00000011 4 17 -b00000011 8 0< -b00000011 = -0? +b00000010 = #47500000 0, 0/ #50000000 1' +b00000010 ) 1, b00001010 . 1/ 13 -b00000011 9 +b00000010 8 +b00000010 9 1< -1? +b00000010 ? #52500000 0, 0/ @@ -267,11 +275,16 @@ b00000011 9 b00000100 # b00000100 % 1& +b00000011 ) 1, b00001011 . 1/ 12 b00000100 4 +b00000011 8 +b00000011 9 +b00000011 = +b00000011 ? #57500000 0, 0/ @@ -294,6 +307,8 @@ b00000100 9 1: b00000100 = 1> +b00000100 ? +1@ #62500000 0, 0/ @@ -302,19 +317,14 @@ b00000100 = b00000010 # b00000010 % 0' -b00000010 ) -0* 1, b00001101 . 1/ 03 b00000010 4 -06 -b00000010 8 0< -b00000010 = +b00000001 = 0> -0? #67500000 0, 0/ @@ -331,16 +341,21 @@ b00001110 . #75000000 1" 1' +b00000001 ) +0* 0+ 1, b00001111 . 1/ 13 +06 07 -b00000010 9 +b00000001 8 +b00000001 9 0: 1< -1? +b00000001 ? +0@ #77500000 0, 0/ @@ -348,7 +363,6 @@ b00000010 9 b00000011 # b00000011 % 0' -b00000011 ) 1+ 1, b00010000 . @@ -356,22 +370,22 @@ b00010000 . 03 b00000011 4 17 -b00000011 8 0< -b00000011 = -0? +b00000010 = #82500000 0, 0/ #85000000 1' +b00000010 ) 1, b00010001 . 1/ 13 -b00000011 9 +b00000010 8 +b00000010 9 1< -1? +b00000010 ? #87500000 0, 0/ @@ -380,11 +394,16 @@ b00000011 9 b00000100 # b00000100 % 1& +b00000011 ) 1, b00010010 . 1/ 12 b00000100 4 +b00000011 8 +b00000011 9 +b00000011 = +b00000011 ? #92500000 0, 0/ @@ -392,7 +411,6 @@ b00000100 4 0$ b00000000 % 0& -0( b00000100 ) 1* 1, @@ -401,30 +419,34 @@ b00010011 . 01 02 b00000000 4 -05 16 b00000100 8 b00000100 9 1: -0; b00000100 = 1> -0@ +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/ @@ -440,15 +462,11 @@ b00010101 . b00000001 # 1$ b00000001 % -1( 1, b00010110 . 1/ 11 b00000001 4 -15 -1; -1@ #112500000 0, 0/ @@ -456,14 +474,18 @@ b00000001 4 0! b00000010 # b00000010 % +1( b00000001 ) 1, b00010111 . 1/ b00000010 4 +15 b00000001 8 b00000001 9 +1; b00000001 = +b00000001 ? #117500000 0, 0/ @@ -471,19 +493,16 @@ b00000001 = 1! 0$ b00000000 % -0( b00000010 ) 1, b00011000 . 1/ 01 b00000000 4 -05 b00000010 8 b00000010 9 -0; b00000010 = -0@ +b00000010 ? #122500000 0, 0/ @@ -491,19 +510,19 @@ b00000010 = b00000011 # 1$ b00000011 % -1( +0( b00000000 ) 1, b00011001 . 1/ 11 b00000011 4 -15 +05 b00000000 8 b00000000 9 -1; +0; b00000000 = -1@ +b00000000 ? #127500000 0, 0/ @@ -512,15 +531,19 @@ b00000000 = b00000100 # b00000100 % 1& +1( b00000011 ) 1, b00011010 . 1/ 12 b00000100 4 +15 b00000011 8 b00000011 9 +1; b00000011 = +b00000011 ? #132500000 0, 0/ @@ -528,7 +551,6 @@ b00000011 = 0$ b00000000 % 0& -0( b00000100 ) 1* 1, @@ -537,30 +559,34 @@ b00011011 . 01 02 b00000000 4 -05 16 b00000100 8 b00000100 9 1: -0; b00000100 = 1> -0@ +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/ diff --git a/ghdl/waveform.gtkw b/ghdl/waveform.gtkw index 8e76741..a140493 100644 --- a/ghdl/waveform.gtkw +++ b/ghdl/waveform.gtkw @@ -1,20 +1,20 @@ [*] [*] GTKWave Analyzer v3.3.100 (w)1999-2019 BSI -[*] Wed Apr 19 14:08:18 2023 +[*] Fri Apr 21 06:49:43 2023 [*] -[dumpfile] "C:\Users\simon\Downloads\P9\ghdl-axi-sim\skid\wave.vcd" -[dumpfile_mtime] "Wed Apr 19 13:44:56 2023" -[dumpfile_size] 14757 -[savefile] "C:\Users\simon\Downloads\P9\ghdl-axi-sim\skid\waveform.gtkw" +[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 -*-24.000000 98390000 -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 +*-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] 314 +[sst_vpaned_height] 361 @24 [color] 5 tb_skid.clk_count[7:0] @@ -26,17 +26,19 @@ 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_tlast tb_skid.s_axis_tready [color] 2 tb_skid.m_axis_tvalid @22 [color] 2 tb_skid.m_axis_tdata[7:0] -@28 +@29 [color] 2 -tb_skid.m_axis_tlast +tb_skid.s_axis_tlast +@28 [color] 2 tb_skid.m_axis_tready [pattern_trace] 1 diff --git a/img/gtkwave_fullreg.png b/img/gtkwave_fullreg.png new file mode 100644 index 0000000000000000000000000000000000000000..5712598ca97ab9030eb40cf7aa834bff1c780e2c GIT binary patch literal 17668 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 literal 0 HcmV?d00001 diff --git a/img/skidbuf_fullreg.png b/img/skidbuf_fullreg.png new file mode 100644 index 0000000000000000000000000000000000000000..c63c1365c9e39d1e23c53484b2df1956475aea0e GIT binary patch literal 38936 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 + + +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 0000000000000000000000000000000000000000..3eba0f4132a17c087704e273d811255cf9429ce0 GIT binary patch literal 37832 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 G{QnQY(9d!J literal 0 HcmV?d00001 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/wavedrom.svg b/img/skidbuf_passthru_wave.svg similarity index 57% rename from img/wavedrom.svg rename to img/skidbuf_passthru_wave.svg index 0abe8fd..2f6ba2b 100644 --- a/img/wavedrom.svg +++ b/img/skidbuf_passthru_wave.svg @@ -1,4 +1,4 @@ -2345678910111213141516171819202122232425262728aclks_valid 🡲s_data 🡲1234123412341234reg_data1234123412341234s_ready 🡠m_valid 🡲m_data 🡲1234123412341234m_ready 🡠 \ No newline at end of file +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 @@ +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 \ No newline at end of file From 28a1daf473c8e0919ac916d0d4dbada37a72f7ef Mon Sep 17 00:00:00 2001 From: Simon Burkhardt Date: Fri, 21 Apr 2023 16:21:16 +0200 Subject: [PATCH 4/7] start AXI4 to AXIS converter --- ghdl/axi4-to-axis/axi4_to_axis.vhd | 406 ++++ ghdl/axi4-to-axis/axis_pipeline.vhd | 149 ++ ghdl/axi4-to-axis/compile.bat | 27 + ghdl/{ => axi4-to-axis}/skidbuffer.vhd | 0 ghdl/axi4-to-axis/tb_axis.vhd | 409 ++++ ghdl/axi4-to-axis/wave.vcd | 2766 ++++++++++++++++++++++ ghdl/axi4-to-axis/waveform.gtkw | 62 + ghdl/axis/axis_pipeline.vhd | 149 ++ ghdl/axis/compile.bat | 25 + ghdl/axis/skidbuffer.vhd | 147 ++ ghdl/axis/tb_axis.vhd | 254 +++ ghdl/axis/wave.vcd | 2907 ++++++++++++++++++++++++ ghdl/axis/waveform.gtkw | 43 + ghdl/{ => basic}/compile.bat | 2 - ghdl/basic/skidbuffer.vhd | 147 ++ ghdl/{ => basic}/tb_skid.vhd | 0 ghdl/{ => basic}/wave.vcd | 0 ghdl/{ => basic}/waveform.gtkw | 0 18 files changed, 7491 insertions(+), 2 deletions(-) create mode 100644 ghdl/axi4-to-axis/axi4_to_axis.vhd create mode 100644 ghdl/axi4-to-axis/axis_pipeline.vhd create mode 100644 ghdl/axi4-to-axis/compile.bat rename ghdl/{ => axi4-to-axis}/skidbuffer.vhd (100%) create mode 100644 ghdl/axi4-to-axis/tb_axis.vhd create mode 100644 ghdl/axi4-to-axis/wave.vcd create mode 100644 ghdl/axi4-to-axis/waveform.gtkw create mode 100644 ghdl/axis/axis_pipeline.vhd create mode 100644 ghdl/axis/compile.bat create mode 100644 ghdl/axis/skidbuffer.vhd create mode 100644 ghdl/axis/tb_axis.vhd create mode 100644 ghdl/axis/wave.vcd create mode 100644 ghdl/axis/waveform.gtkw rename ghdl/{ => basic}/compile.bat (82%) create mode 100644 ghdl/basic/skidbuffer.vhd rename ghdl/{ => basic}/tb_skid.vhd (100%) rename ghdl/{ => basic}/wave.vcd (100%) rename ghdl/{ => basic}/waveform.gtkw (100%) 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..91368cd --- /dev/null +++ b/ghdl/axi4-to-axis/axi4_to_axis.vhd @@ -0,0 +1,406 @@ +---------------------------------------------------------------------------------- +-- 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; + + -- Width of S_AXIS address bus. The slave accepts the read and write addresses of width C_M_AXIS_DATA_WIDTH. + C_M_AXIS_DATA_WIDTH : integer := 32 + ); + 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_M_AXIS_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_M_AXIS_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_M_AXIS_DATA_WIDTH+(C_M_AXIS_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_M_AXIS_DATA_WIDTH+(C_M_AXIS_DATA_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_M_AXIS_DATA_WIDTH-1 downto 0); + signal i_axis_data_strb : std_logic_vector(C_M_AXIS_DATA_WIDTH+(C_M_AXIS_DATA_WIDTH/8)-1 downto 0); + signal i_s_axis_tstrb : std_logic_vector((C_M_AXIS_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_M_AXIS_DATA_WIDTH-1 downto 0); + signal o_axis_data_strb : std_logic_vector(C_M_AXIS_DATA_WIDTH+(C_M_AXIS_DATA_WIDTH/8)-1 downto 0); + signal o_m_axis_tstrb : std_logic_vector((C_M_AXIS_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_s_axi_bresp : std_logic_vector(1 downto 0); + signal o_s_axi_bvalid : std_logic; + signal o_s_axi_bid : std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + signal i_s_axi_bready : std_logic; + + signal temp_bid : std_logic_vector(C_S_AXI_ID_WIDTH-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 + 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_s_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_s_axi_bresp; + S_AXI_BVALID <= o_s_axi_bvalid; + S_AXI_BID <= o_s_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_axis_data_strb <= i_s_axis_tdata & i_s_axis_tstrb; + o_m_axis_tdata <= o_axis_data_strb( (C_M_AXIS_DATA_WIDTH+(C_M_AXIS_DATA_WIDTH/8)) - 1 downto (C_M_AXIS_DATA_WIDTH/8) ); + o_m_axis_tstrb <= o_axis_data_strb( (C_M_AXIS_DATA_WIDTH/8) - 1 downto 0 ); + + p_accept_aw : process(aclk) + begin + if rising_edge(aclk) then + if aresetn = '0' then + o_axi_awready <= '1'; + else + if i_axi_awvalid = '1' then + o_axi_awready <= '0'; + temp_bid <= i_axi_awid; -- remember for BID in BRESP + else + o_axi_awready <= '1'; + end if; + end if; + end if; + end process; + + p_bresp : process(aclk) + begin + if rising_edge(aclk) then + if aresetn = '0' then + o_s_axi_bvalid <= '0'; + o_s_axi_bresp <= (others => '0'); + o_s_axi_bid <= (others => '0'); + else + if o_s_axi_bvalid = '1' then -- waiting for ack from master + if i_s_axi_bready = '1' then -- master did ack + o_s_axi_bvalid <= '0'; -- BRESP complete + o_s_axi_bresp <= (others => '0'); + o_s_axi_bid <= (others => '0'); + end if; + else -- wait to generate a BRESP + -- TODO this if statement is won't work for non-burst transfers wher tlast is not used + if o_m_axis_tlast = '1' and i_m_axis_tready = '1' then + o_s_axi_bvalid <= '1'; + o_s_axi_bresp <= "00"; -- TODO is this 0b00 => "OKAY"? + o_s_axi_bid <= temp_bid; -- TODO write temp_bid in AW accept process + end if; + end if; + end if; + end if; + end process; + + + skidbuffer_inst : skidbuffer + generic map ( + DATA_WIDTH => (C_M_AXIS_DATA_WIDTH+(C_M_AXIS_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_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/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/skidbuffer.vhd b/ghdl/axi4-to-axis/skidbuffer.vhd similarity index 100% rename from ghdl/skidbuffer.vhd rename to ghdl/axi4-to-axis/skidbuffer.vhd diff --git a/ghdl/axi4-to-axis/tb_axis.vhd b/ghdl/axi4-to-axis/tb_axis.vhd new file mode 100644 index 0000000..c4eb6b1 --- /dev/null +++ b/ghdl/axi4-to-axis/tb_axis.vhd @@ -0,0 +1,409 @@ +---------------------------------------------------------------------------------- +-- 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; + + -- Width of S_AXIS address bus. The slave accepts the read and write addresses of width C_M_AXIS_DATA_WIDTH. + C_M_AXIS_DATA_WIDTH : integer := 8 + ); +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; + C_M_AXIS_DATA_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_M_AXIS_DATA_WIDTH-1 downto 0); + M_AXIS_TSTRB : out std_logic_vector((C_M_AXIS_DATA_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'; + signal sim_data : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + signal sim_valid_data : std_logic := '0'; + + signal o_axis_tvalid : std_logic; + signal o_axis_tdata : std_logic_vector(C_M_AXIS_DATA_WIDTH-1 downto 0); + signal o_axis_tstrb : std_logic_vector((C_M_AXIS_DATA_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'); +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; + + i_axis_tready <= '1'; -- TODO REMOVE + + -- 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; + 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'; + else + if sim_valid_data = '1' then -- OK from a valid AW handshake + if i_axi_wready = '1' then -- wready from slave + if unsigned(o_axi_wdata) = 63 then + o_axi_wlast <= '1'; + else + o_axi_wlast <= '0'; + end if; + + if unsigned(o_axi_wdata) = 64 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) = 64 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; + else + o_axi_wdata <= o_axi_wdata; + sim_data <= sim_data; + end if; + o_axi_wvalid <= '1'; + o_axi_wstrb <= "1"; + 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; + + -- generate ready signal + p_stimuli_tready : process(clk) + begin + if rising_edge(clk) then + if rst_n = '0' then + sim_start_write <= '0'; + else + if unsigned(clk_count) = 3 then + sim_start_write <= '1'; + end if; + if unsigned(clk_count) = 4 then + sim_start_write <= '0'; + 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, + C_M_AXIS_DATA_WIDTH => C_M_AXIS_DATA_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..f5a89f6 --- /dev/null +++ b/ghdl/axi4-to-axis/wave.vcd @@ -0,0 +1,2766 @@ +$date + Fri Apr 21 15:21:41 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 8 " sim_data[7:0] $end +$var reg 1 # sim_valid_data $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 / o_axi_awburst[1:0] $end +$var reg 1 0 o_axi_awlock $end +$var reg 4 1 o_axi_awcache[3:0] $end +$var reg 3 2 o_axi_awprot[2:0] $end +$var reg 4 3 o_axi_awqos[3:0] $end +$var reg 4 4 o_axi_awregion[3:0] $end +$comment o_axi_awuser is not handled $end +$var reg 1 5 o_axi_awvalid $end +$var reg 1 6 i_axi_awready $end +$var reg 8 7 o_axi_wdata[7:0] $end +$var reg 1 8 o_axi_wstrb[0:0] $end +$var reg 1 9 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 @ o_axi_arid[2:0] $end +$var reg 8 A o_axi_araddr[7:0] $end +$var reg 8 B o_axi_arlen[7:0] $end +$var reg 3 C o_axi_arsize[2:0] $end +$var reg 2 D o_axi_arburst[1:0] $end +$var reg 1 E o_axi_arlock $end +$var reg 4 F o_axi_arcache[3:0] $end +$var reg 3 G o_axi_arprot[2:0] $end +$var reg 4 H o_axi_arqos[3:0] $end +$var reg 4 I o_axi_arregion[3:0] $end +$comment o_axi_aruser is not handled $end +$var reg 1 J o_axi_arvalid $end +$var reg 1 K i_axi_arready $end +$var reg 3 L i_axi_rid[2:0] $end +$var reg 8 M i_axi_rdata[7:0] $end +$var reg 2 N i_axi_rresp[1:0] $end +$var reg 1 O i_axi_rlast $end +$comment i_axi_ruser is not handled $end +$var reg 1 P i_axi_rvalid $end +$var reg 1 Q o_axi_rready $end +$var reg 8 R clk_count[7:0] $end +$scope module axi_converter_inst $end +$var reg 1 S axis_aclk $end +$var reg 1 T axis_aresetn $end +$var reg 3 U s_axi_awid[2:0] $end +$var reg 8 V s_axi_awaddr[7:0] $end +$var reg 8 W s_axi_awlen[7:0] $end +$var reg 3 X s_axi_awsize[2:0] $end +$var reg 2 Y s_axi_awburst[1:0] $end +$var reg 1 Z 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 _ s_axi_awvalid $end +$var reg 1 ` s_axi_awready $end +$var reg 8 a s_axi_wdata[7:0] $end +$var reg 1 b s_axi_wstrb[0:0] $end +$var reg 1 c s_axi_wlast $end +$comment s_axi_wuser is not handled $end +$var reg 1 d s_axi_wvalid $end +$var reg 1 e s_axi_wready $end +$var reg 3 f s_axi_bid[2:0] $end +$var reg 2 g s_axi_bresp[1:0] $end +$comment s_axi_buser is not handled $end +$var reg 1 h s_axi_bvalid $end +$var reg 1 i s_axi_bready $end +$var reg 3 j s_axi_arid[2:0] $end +$var reg 8 k s_axi_araddr[7:0] $end +$var reg 8 l s_axi_arlen[7:0] $end +$var reg 3 m s_axi_arsize[2:0] $end +$var reg 2 n s_axi_arburst[1:0] $end +$var reg 1 o s_axi_arlock $end +$var reg 4 p s_axi_arcache[3:0] $end +$var reg 3 q s_axi_arprot[2:0] $end +$var reg 4 r s_axi_arqos[3:0] $end +$var reg 4 s s_axi_arregion[3:0] $end +$comment s_axi_aruser is not handled $end +$var reg 1 t s_axi_arvalid $end +$var reg 1 u s_axi_arready $end +$var reg 3 v s_axi_rid[2:0] $end +$var reg 8 w s_axi_rdata[7:0] $end +$var reg 2 x s_axi_rresp[1:0] $end +$var reg 1 y s_axi_rlast $end +$comment s_axi_ruser is not handled $end +$var reg 1 z 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 +$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_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 ." o_axis_data_strb[8:0] $end +$var reg 1 /" o_m_axis_tstrb[0:0] $end +$var reg 1 0" o_m_axis_tlast $end +$var reg 1 1" i_m_axis_tready $end +$var reg 2 2" o_s_axi_bresp[1:0] $end +$var reg 1 3" o_s_axi_bvalid $end +$var reg 3 4" o_s_axi_bid[2:0] $end +$var reg 1 5" i_s_axi_bready $end +$var reg 3 6" temp_bid[2: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! +bUUUUUUUU " +0# +U$ +bUUUUUUUU % +bU & +U' +1( +1) +0* +bUUU + +bUUUUUUUU , +bUUUUUUUU - +bUUU . +bUU / +U0 +bUUUU 1 +bUUU 2 +bUUUU 3 +bUUUU 4 +U5 +U6 +bUUUUUUUU 7 +bU 8 +U9 +U: +U; +bUUU < +bUU = +U> +U? +bUUU @ +bUUUUUUUU A +bUUUUUUUU B +bUUU C +bUU D +UE +bUUUU F +bUUU G +bUUUU H +bUUUU I +UJ +UK +bUUU L +bUUUUUUUU M +bUU N +UO +UP +UQ +b00000000 R +1S +0T +bUUU U +bUUUUUUUU V +bUUUUUUUU W +bUUU X +bUU Y +UZ +bUUUU [ +bUUU \ +bUUUU ] +bUUUU ^ +U_ +U` +bUUUUUUUU a +bU b +Uc +Ud +Ue +bUUU f +bUU g +Uh +Ui +bUUU j +bUUUUUUUU k +bUUUUUUUU l +bUUU m +bUU n +Uo +bUUUU p +bUUU q +bUUUU r +bUUUU s +Ut +Uu +bUUU v +bUUUUUUUU w +bUU x +Uy +Uz +U{ +U| +bUUUUUUUU } +bU !" +U"" +1#" +1$" +0%" +U&" +bUUUUUUUU '" +bUUUUUUUUU (" +bU )" +U*" +U+" +U," +bUUUUUUUU -" +bUUUUUUUUU ." +bU /" +U0" +11" +bUU 2" +U3" +bUUU 4" +U5" +bUUU 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" +1f" +bUUUUUUUUU g" +bUUUUUUUUU h" +Ui" +Uj" +Uk" +bUUUUUUUUU l" +Um" +bUUUUUUUUU n" +Uo" +#2500000 +0) +0S +0$" +0^" +#5000000 +b00000000 " +0$ +b00000000 % +b0 & +0' +1) +b000 + +b00000000 , +b00000000 - +b000 . +b00 / +00 +b0000 1 +b000 2 +b0000 3 +b0000 4 +05 +16 +b00000000 7 +b0 8 +09 +b000 < +b00 = +0> +b00000001 R +1S +b000 U +b00000000 V +b00000000 W +b000 X +b00 Y +0Z +b0000 [ +b000 \ +b0000 ] +b0000 ^ +0_ +1` +b00000000 a +b0 b +0c +Ue +b000 f +b00 g +0h +0| +b00000000 } +b0 !" +0"" +1$" +b00000000 '" +b000000000 (" +b0 )" +0*" +0+" +0," +b00000000 -" +b000000000 ." +b0 /" +00" +b00 2" +03" +b000 4" +b000 7" +b00000000 8" +b00000000 9" +b000 :" +b00 ;" +0<" +b0000 =" +b000 >" +b0000 ?" +b0000 @" +0A" +1B" +b00000000 C" +b0 D" +0E" +1^" +0a" +0b" +b000000000 c" +0d" +0e" +b000000000 g" +b000000000 h" +0i" +0j" +0k" +b000000000 l" +0m" +b000000000 n" +0o" +#6250000 +1* +1T +1%" +1_" +#7500000 +0) +0S +0$" +0^" +#10000000 +U$ +1) +0: +b00000010 R +1S +0d +Ue +U| +1$" +0&" +1+" +U," +0F" +1^" +0`" +1b" +Ud" +Uj" +1k" +#12500000 +0) +0S +0$" +0^" +#15000000 +1! +0$ +1) +b00000011 R +1S +0| +1$" +0," +1^" +0d" +0j" +#17500000 +0) +0S +0$" +0^" +#20000000 +0! +1) +b101 + +b01000010 , +b00111111 - +b110 . +b01 / +15 +b00000100 R +1S +b101 U +b01000010 V +b00111111 W +b110 X +b01 Y +1_ +1$" +b101 7" +b01000010 8" +b00111111 9" +b110 :" +b01 ;" +1A" +1^" +#22500000 +0) +0S +0$" +0^" +#25000000 +1# +1) +b000 + +b00000000 , +b00000000 - +b000 . +b00 / +05 +06 +b00000101 R +1S +b000 U +b00000000 V +b00000000 W +b000 X +b00 Y +0_ +0` +1$" +b101 6" +b000 7" +b00000000 8" +b00000000 9" +b000 :" +b00 ;" +0A" +0B" +1^" +#27500000 +0) +0S +0$" +0^" +#30000000 +1) +16 +b1 8 +1: +b00000110 R +1S +1` +b1 b +1d +1$" +1&" +b000000001 (" +b1 )" +1B" +b1 D" +1F" +1^" +1`" +b000000001 c" +#32500000 +0) +0S +0$" +0^" +#35000000 +1$ +b1 & +1) +b00000111 R +1S +1| +b1 !" +1$" +1," +b000000001 ." +b1 /" +1^" +1d" +b000000001 g" +b000000001 h" +1j" +b000000001 l" +b000000001 n" +#37500000 +0) +0S +0$" +0^" +#40000000 +1) +b00001000 R +1S +1$" +1^" +#42500000 +0) +0S +0$" +0^" +#45000000 +1) +b00001001 R +1S +1$" +1^" +#47500000 +0) +0S +0$" +0^" +#50000000 +1) +b00001010 R +1S +1$" +1^" +#52500000 +0) +0S +0$" +0^" +#55000000 +1) +b00001011 R +1S +1$" +1^" +#57500000 +0) +0S +0$" +0^" +#60000000 +1) +b00001100 R +1S +1$" +1^" +#62500000 +0) +0S +0$" +0^" +#65000000 +1) +b00001101 R +1S +1$" +1^" +#67500000 +0) +0S +0$" +0^" +#70000000 +1) +b00001110 R +1S +1$" +1^" +#72500000 +0) +0S +0$" +0^" +#75000000 +1) +b00001111 R +1S +1$" +1^" +#77500000 +0) +0S +0$" +0^" +#80000000 +1) +b00010000 R +1S +1$" +1^" +#82500000 +0) +0S +0$" +0^" +#85000000 +1) +b00010001 R +1S +1$" +1^" +#87500000 +0) +0S +0$" +0^" +#90000000 +1) +b00010010 R +1S +1$" +1^" +#92500000 +0) +0S +0$" +0^" +#95000000 +1) +b00010011 R +1S +1$" +1^" +#97500000 +0) +0S +0$" +0^" +#100000000 +1) +b00010100 R +1S +1$" +1^" +#102500000 +0) +0S +0$" +0^" +#105000000 +1) +b00010101 R +1S +1$" +1^" +#107500000 +0) +0S +0$" +0^" +#110000000 +1) +b00010110 R +1S +1$" +1^" +#112500000 +0) +0S +0$" +0^" +#115000000 +1) +b00010111 R +1S +1$" +1^" +#117500000 +0) +0S +0$" +0^" +#120000000 +1) +b00011000 R +1S +1$" +1^" +#122500000 +0) +0S +0$" +0^" +#125000000 +1) +b00011001 R +1S +1$" +1^" +#127500000 +0) +0S +0$" +0^" +#130000000 +1) +b00011010 R +1S +1$" +1^" +#132500000 +0) +0S +0$" +0^" +#135000000 +1) +b00011011 R +1S +1$" +1^" +#137500000 +0) +0S +0$" +0^" +#140000000 +1) +b00011100 R +1S +1$" +1^" +#142500000 +0) +0S +0$" +0^" +#145000000 +1) +b00011101 R +1S +1$" +1^" +#147500000 +0) +0S +0$" +0^" +#150000000 +1) +b00011110 R +1S +1$" +1^" +#152500000 +0) +0S +0$" +0^" +#155000000 +1) +b00011111 R +1S +1$" +1^" +#157500000 +0) +0S +0$" +0^" +#160000000 +1) +b00100000 R +1S +1$" +1^" +#162500000 +0) +0S +0$" +0^" +#165000000 +1) +b00100001 R +1S +1$" +1^" +#167500000 +0) +0S +0$" +0^" +#170000000 +1) +b00100010 R +1S +1$" +1^" +#172500000 +0) +0S +0$" +0^" +#175000000 +1) +b00100011 R +1S +1$" +1^" +#177500000 +0) +0S +0$" +0^" +#180000000 +1) +b00100100 R +1S +1$" +1^" +#182500000 +0) +0S +0$" +0^" +#185000000 +1) +b00100101 R +1S +1$" +1^" +#187500000 +0) +0S +0$" +0^" +#190000000 +1) +b00100110 R +1S +1$" +1^" +#192500000 +0) +0S +0$" +0^" +#195000000 +1) +b00100111 R +1S +1$" +1^" +#197500000 +0) +0S +0$" +0^" +#200000000 +1) +b00101000 R +1S +1$" +1^" +#202500000 +0) +0S +0$" +0^" +#205000000 +1) +b00101001 R +1S +1$" +1^" +#207500000 +0) +0S +0$" +0^" +#210000000 +1) +b00101010 R +1S +1$" +1^" +#212500000 +0) +0S +0$" +0^" +#215000000 +1) +b00101011 R +1S +1$" +1^" +#217500000 +0) +0S +0$" +0^" +#220000000 +1) +b00101100 R +1S +1$" +1^" +#222500000 +0) +0S +0$" +0^" +#225000000 +1) +b00101101 R +1S +1$" +1^" +#227500000 +0) +0S +0$" +0^" +#230000000 +1) +b00101110 R +1S +1$" +1^" +#232500000 +0) +0S +0$" +0^" +#235000000 +1) +b00101111 R +1S +1$" +1^" +#237500000 +0) +0S +0$" +0^" +#240000000 +1) +b00110000 R +1S +1$" +1^" +#242500000 +0) +0S +0$" +0^" +#245000000 +1) +b00110001 R +1S +1$" +1^" +#247500000 +0) +0S +0$" +0^" +#250000000 +1) +b00110010 R +1S +1$" +1^" +#252500000 +0) +0S +0$" +0^" +#255000000 +1) +b00110011 R +1S +1$" +1^" +#257500000 +0) +0S +0$" +0^" +#260000000 +1) +b00110100 R +1S +1$" +1^" +#262500000 +0) +0S +0$" +0^" +#265000000 +1) +b00110101 R +1S +1$" +1^" +#267500000 +0) +0S +0$" +0^" +#270000000 +1) +b00110110 R +1S +1$" +1^" +#272500000 +0) +0S +0$" +0^" +#275000000 +1) +b00110111 R +1S +1$" +1^" +#277500000 +0) +0S +0$" +0^" +#280000000 +1) +b00111000 R +1S +1$" +1^" +#282500000 +0) +0S +0$" +0^" +#285000000 +1) +b00111001 R +1S +1$" +1^" +#287500000 +0) +0S +0$" +0^" +#290000000 +1) +b00111010 R +1S +1$" +1^" +#292500000 +0) +0S +0$" +0^" +#295000000 +1) +b00111011 R +1S +1$" +1^" +#297500000 +0) +0S +0$" +0^" +#300000000 +1) +b00111100 R +1S +1$" +1^" +#302500000 +0) +0S +0$" +0^" +#305000000 +1) +b00111101 R +1S +1$" +1^" +#307500000 +0) +0S +0$" +0^" +#310000000 +1) +b00111110 R +1S +1$" +1^" +#312500000 +0) +0S +0$" +0^" +#315000000 +1) +b00111111 R +1S +1$" +1^" +#317500000 +0) +0S +0$" +0^" +#320000000 +1) +b01000000 R +1S +1$" +1^" +#322500000 +0) +0S +0$" +0^" +#325000000 +1) +b01000001 R +1S +1$" +1^" +#327500000 +0) +0S +0$" +0^" +#330000000 +1) +b01000010 R +1S +1$" +1^" +#332500000 +0) +0S +0$" +0^" +#335000000 +1) +b01000011 R +1S +1$" +1^" +#337500000 +0) +0S +0$" +0^" +#340000000 +1) +b01000100 R +1S +1$" +1^" +#342500000 +0) +0S +0$" +0^" +#345000000 +1) +b01000101 R +1S +1$" +1^" +#347500000 +0) +0S +0$" +0^" +#350000000 +1) +b01000110 R +1S +1$" +1^" +#352500000 +0) +0S +0$" +0^" +#355000000 +1) +b01000111 R +1S +1$" +1^" +#357500000 +0) +0S +0$" +0^" +#360000000 +1) +b01001000 R +1S +1$" +1^" +#362500000 +0) +0S +0$" +0^" +#365000000 +1) +b01001001 R +1S +1$" +1^" +#367500000 +0) +0S +0$" +0^" +#370000000 +1) +b01001010 R +1S +1$" +1^" +#372500000 +0) +0S +0$" +0^" +#375000000 +1) +b01001011 R +1S +1$" +1^" +#377500000 +0) +0S +0$" +0^" +#380000000 +1) +b01001100 R +1S +1$" +1^" +#382500000 +0) +0S +0$" +0^" +#385000000 +1) +b01001101 R +1S +1$" +1^" +#387500000 +0) +0S +0$" +0^" +#390000000 +1) +b01001110 R +1S +1$" +1^" +#392500000 +0) +0S +0$" +0^" +#395000000 +1) +b01001111 R +1S +1$" +1^" +#397500000 +0) +0S +0$" +0^" +#400000000 +1) +b01010000 R +1S +1$" +1^" +#402500000 +0) +0S +0$" +0^" +#405000000 +1) +b01010001 R +1S +1$" +1^" +#407500000 +0) +0S +0$" +0^" +#410000000 +1) +b01010010 R +1S +1$" +1^" +#412500000 +0) +0S +0$" +0^" +#415000000 +1) +b01010011 R +1S +1$" +1^" +#417500000 +0) +0S +0$" +0^" +#420000000 +1) +b01010100 R +1S +1$" +1^" +#422500000 +0) +0S +0$" +0^" +#425000000 +1) +b01010101 R +1S +1$" +1^" +#427500000 +0) +0S +0$" +0^" +#430000000 +1) +b01010110 R +1S +1$" +1^" +#432500000 +0) +0S +0$" +0^" +#435000000 +1) +b01010111 R +1S +1$" +1^" +#437500000 +0) +0S +0$" +0^" +#440000000 +1) +b01011000 R +1S +1$" +1^" +#442500000 +0) +0S +0$" +0^" +#445000000 +1) +b01011001 R +1S +1$" +1^" +#447500000 +0) +0S +0$" +0^" +#450000000 +1) +b01011010 R +1S +1$" +1^" +#452500000 +0) +0S +0$" +0^" +#455000000 +1) +b01011011 R +1S +1$" +1^" +#457500000 +0) +0S +0$" +0^" +#460000000 +1) +b01011100 R +1S +1$" +1^" +#462500000 +0) +0S +0$" +0^" +#465000000 +1) +b01011101 R +1S +1$" +1^" +#467500000 +0) +0S +0$" +0^" +#470000000 +1) +b01011110 R +1S +1$" +1^" +#472500000 +0) +0S +0$" +0^" +#475000000 +1) +b01011111 R +1S +1$" +1^" +#477500000 +0) +0S +0$" +0^" +#480000000 +1) +b01100000 R +1S +1$" +1^" +#482500000 +0) +0S +0$" +0^" +#485000000 +1) +b01100001 R +1S +1$" +1^" +#487500000 +0) +0S +0$" +0^" +#490000000 +1) +b01100010 R +1S +1$" +1^" +#492500000 +0) +0S +0$" +0^" +#495000000 +1) +b01100011 R +1S +1$" +1^" +#497500000 +0) +0S +0$" +0^" +#500000000 +1) +b01100100 R +1S +1$" +1^" +#502500000 +0) +0S +0$" +0^" +#505000000 +1) +b01100101 R +1S +1$" +1^" +#507500000 +0) +0S +0$" +0^" +#510000000 +1) +b01100110 R +1S +1$" +1^" +#512500000 +0) +0S +0$" +0^" +#515000000 +1) +b01100111 R +1S +1$" +1^" +#517500000 +0) +0S +0$" +0^" +#520000000 +1) +b01101000 R +1S +1$" +1^" +#522500000 +0) +0S +0$" +0^" +#525000000 +1) +b01101001 R +1S +1$" +1^" +#527500000 +0) +0S +0$" +0^" +#530000000 +1) +b01101010 R +1S +1$" +1^" +#532500000 +0) +0S +0$" +0^" +#535000000 +1) +b01101011 R +1S +1$" +1^" +#537500000 +0) +0S +0$" +0^" +#540000000 +1) +b01101100 R +1S +1$" +1^" +#542500000 +0) +0S +0$" +0^" +#545000000 +1) +b01101101 R +1S +1$" +1^" +#547500000 +0) +0S +0$" +0^" +#550000000 +1) +b01101110 R +1S +1$" +1^" +#552500000 +0) +0S +0$" +0^" +#555000000 +1) +b01101111 R +1S +1$" +1^" +#557500000 +0) +0S +0$" +0^" +#560000000 +1) +b01110000 R +1S +1$" +1^" +#562500000 +0) +0S +0$" +0^" +#565000000 +1) +b01110001 R +1S +1$" +1^" +#567500000 +0) +0S +0$" +0^" +#570000000 +1) +b01110010 R +1S +1$" +1^" +#572500000 +0) +0S +0$" +0^" +#575000000 +1) +b01110011 R +1S +1$" +1^" +#577500000 +0) +0S +0$" +0^" +#580000000 +1) +b01110100 R +1S +1$" +1^" +#582500000 +0) +0S +0$" +0^" +#585000000 +1) +b01110101 R +1S +1$" +1^" +#587500000 +0) +0S +0$" +0^" +#590000000 +1) +b01110110 R +1S +1$" +1^" +#592500000 +0) +0S +0$" +0^" +#595000000 +1) +b01110111 R +1S +1$" +1^" +#597500000 +0) +0S +0$" +0^" +#600000000 +1) +b01111000 R +1S +1$" +1^" +#602500000 +0) +0S +0$" +0^" +#605000000 +1) +b01111001 R +1S +1$" +1^" +#607500000 +0) +0S +0$" +0^" +#610000000 +1) +b01111010 R +1S +1$" +1^" +#612500000 +0) +0S +0$" +0^" +#615000000 +1) +b01111011 R +1S +1$" +1^" +#617500000 +0) +0S +0$" +0^" +#620000000 +1) +b01111100 R +1S +1$" +1^" +#622500000 +0) +0S +0$" +0^" +#625000000 +1) +b01111101 R +1S +1$" +1^" +#627500000 +0) +0S +0$" +0^" +#630000000 +1) +b01111110 R +1S +1$" +1^" +#632500000 +0) +0S +0$" +0^" +#635000000 +1) +b01111111 R +1S +1$" +1^" +#637500000 +0) +0S +0$" +0^" +#640000000 +1) +b10000000 R +1S +1$" +1^" +#642500000 +0) +0S +0$" +0^" +#645000000 +1) +b10000001 R +1S +1$" +1^" +#647500000 +0) +0S +0$" +0^" +#650000000 +1) +b10000010 R +1S +1$" +1^" +#652500000 +0) +0S +0$" +0^" +#655000000 +1) +b10000011 R +1S +1$" +1^" +#657500000 +0) +0S +0$" +0^" +#660000000 +1) +b10000100 R +1S +1$" +1^" +#662500000 +0) +0S +0$" +0^" +#665000000 +1) +b10000101 R +1S +1$" +1^" +#667500000 +0) +0S +0$" +0^" +#670000000 +1) +b10000110 R +1S +1$" +1^" +#672500000 +0) +0S +0$" +0^" +#675000000 +1) +b10000111 R +1S +1$" +1^" +#677500000 +0) +0S +0$" +0^" +#680000000 +1) +b10001000 R +1S +1$" +1^" +#682500000 +0) +0S +0$" +0^" +#685000000 +1) +b10001001 R +1S +1$" +1^" +#687500000 +0) +0S +0$" +0^" +#690000000 +1) +b10001010 R +1S +1$" +1^" +#692500000 +0) +0S +0$" +0^" +#695000000 +1) +b10001011 R +1S +1$" +1^" +#697500000 +0) +0S +0$" +0^" +#700000000 +1) +b10001100 R +1S +1$" +1^" +#702500000 +0) +0S +0$" +0^" +#705000000 +1) +b10001101 R +1S +1$" +1^" +#707500000 +0) +0S +0$" +0^" +#710000000 +1) +b10001110 R +1S +1$" +1^" +#712500000 +0) +0S +0$" +0^" +#715000000 +1) +b10001111 R +1S +1$" +1^" +#717500000 +0) +0S +0$" +0^" +#720000000 +1) +b10010000 R +1S +1$" +1^" +#722500000 +0) +0S +0$" +0^" +#725000000 +1) +b10010001 R +1S +1$" +1^" +#727500000 +0) +0S +0$" +0^" +#730000000 +1) +b10010010 R +1S +1$" +1^" +#732500000 +0) +0S +0$" +0^" +#735000000 +1) +b10010011 R +1S +1$" +1^" +#737500000 +0) +0S +0$" +0^" +#740000000 +1) +b10010100 R +1S +1$" +1^" +#742500000 +0) +0S +0$" +0^" +#745000000 +1) +b10010101 R +1S +1$" +1^" +#747500000 +0) +0S +0$" +0^" +#750000000 +1) +b10010110 R +1S +1$" +1^" +#752500000 +0) +0S +0$" +0^" +#755000000 +1) +b10010111 R +1S +1$" +1^" +#757500000 +0) +0S +0$" +0^" +#760000000 +1) +b10011000 R +1S +1$" +1^" +#762500000 +0) +0S +0$" +0^" +#765000000 +1) +b10011001 R +1S +1$" +1^" +#767500000 +0) +0S +0$" +0^" +#770000000 +1) +b10011010 R +1S +1$" +1^" +#772500000 +0) +0S +0$" +0^" +#775000000 +1) +b10011011 R +1S +1$" +1^" +#777500000 +0) +0S +0$" +0^" +#780000000 +1) +b10011100 R +1S +1$" +1^" +#782500000 +0) +0S +0$" +0^" +#785000000 +1) +b10011101 R +1S +1$" +1^" +#787500000 +0) +0S +0$" +0^" +#790000000 +1) +b10011110 R +1S +1$" +1^" +#792500000 +0) +0S +0$" +0^" +#795000000 +1) +b10011111 R +1S +1$" +1^" +#797500000 +0) +0S +0$" +0^" +#800000000 +1) +b10100000 R +1S +1$" +1^" +#802500000 +0) +0S +0$" +0^" +#805000000 +1) +b10100001 R +1S +1$" +1^" +#807500000 +0) +0S +0$" +0^" +#810000000 +1) +b10100010 R +1S +1$" +1^" +#812500000 +0) +0S +0$" +0^" +#815000000 +1) +b10100011 R +1S +1$" +1^" +#817500000 +0) +0S +0$" +0^" +#820000000 +1) +b10100100 R +1S +1$" +1^" +#822500000 +0) +0S +0$" +0^" +#825000000 +1) +b10100101 R +1S +1$" +1^" +#827500000 +0) +0S +0$" +0^" +#830000000 +1) +b10100110 R +1S +1$" +1^" +#832500000 +0) +0S +0$" +0^" +#835000000 +1) +b10100111 R +1S +1$" +1^" +#837500000 +0) +0S +0$" +0^" +#840000000 +1) +b10101000 R +1S +1$" +1^" +#842500000 +0) +0S +0$" +0^" +#845000000 +1) +b10101001 R +1S +1$" +1^" +#847500000 +0) +0S +0$" +0^" +#850000000 +1) +b10101010 R +1S +1$" +1^" +#852500000 +0) +0S +0$" +0^" +#855000000 +1) +b10101011 R +1S +1$" +1^" +#857500000 +0) +0S +0$" +0^" +#860000000 +1) +b10101100 R +1S +1$" +1^" +#862500000 +0) +0S +0$" +0^" +#865000000 +1) +b10101101 R +1S +1$" +1^" +#867500000 +0) +0S +0$" +0^" +#870000000 +1) +b10101110 R +1S +1$" +1^" +#872500000 +0) +0S +0$" +0^" +#875000000 +1) +b10101111 R +1S +1$" +1^" +#877500000 +0) +0S +0$" +0^" +#880000000 +1) +b10110000 R +1S +1$" +1^" +#882500000 +0) +0S +0$" +0^" +#885000000 +1) +b10110001 R +1S +1$" +1^" +#887500000 +0) +0S +0$" +0^" +#890000000 +1) +b10110010 R +1S +1$" +1^" +#892500000 +0) +0S +0$" +0^" +#895000000 +1) +b10110011 R +1S +1$" +1^" +#897500000 +0) +0S +0$" +0^" +#900000000 +1) +b10110100 R +1S +1$" +1^" +#902500000 +0) +0S +0$" +0^" +#905000000 +1) +b10110101 R +1S +1$" +1^" +#907500000 +0) +0S +0$" +0^" +#910000000 +1) +b10110110 R +1S +1$" +1^" +#912500000 +0) +0S +0$" +0^" +#915000000 +1) +b10110111 R +1S +1$" +1^" +#917500000 +0) +0S +0$" +0^" +#920000000 +1) +b10111000 R +1S +1$" +1^" +#922500000 +0) +0S +0$" +0^" +#925000000 +1) +b10111001 R +1S +1$" +1^" +#927500000 +0) +0S +0$" +0^" +#930000000 +1) +b10111010 R +1S +1$" +1^" +#932500000 +0) +0S +0$" +0^" +#935000000 +1) +b10111011 R +1S +1$" +1^" +#937500000 +0) +0S +0$" +0^" +#940000000 +1) +b10111100 R +1S +1$" +1^" +#942500000 +0) +0S +0$" +0^" +#945000000 +1) +b10111101 R +1S +1$" +1^" +#947500000 +0) +0S +0$" +0^" +#950000000 +1) +b10111110 R +1S +1$" +1^" +#952500000 +0) +0S +0$" +0^" +#955000000 +1) +b10111111 R +1S +1$" +1^" +#957500000 +0) +0S +0$" +0^" +#960000000 +1) +b11000000 R +1S +1$" +1^" +#962500000 +0) +0S +0$" +0^" +#965000000 +1) +b11000001 R +1S +1$" +1^" +#967500000 +0) +0S +0$" +0^" +#970000000 +1) +b11000010 R +1S +1$" +1^" +#972500000 +0) +0S +0$" +0^" +#975000000 +1) +b11000011 R +1S +1$" +1^" +#977500000 +0) +0S +0$" +0^" +#980000000 +1) +b11000100 R +1S +1$" +1^" +#982500000 +0) +0S +0$" +0^" +#985000000 +1) +b11000101 R +1S +1$" +1^" +#987500000 +0) +0S +0$" +0^" +#990000000 +1) +b11000110 R +1S +1$" +1^" +#992500000 +0) +0S +0$" +0^" +#995000000 +1) +b11000111 R +1S +1$" +1^" +#997500000 +0) +0S +0$" +0^" +#1000000000 +1) +b11001000 R +1S +1$" +1^" diff --git a/ghdl/axi4-to-axis/waveform.gtkw b/ghdl/axi4-to-axis/waveform.gtkw new file mode 100644 index 0000000..b75759c --- /dev/null +++ b/ghdl/axi4-to-axis/waveform.gtkw @@ -0,0 +1,62 @@ +[*] +[*] GTKWave Analyzer v3.3.100 (w)1999-2019 BSI +[*] Fri Apr 21 12:57:05 2023 +[*] +[dumpfile] "C:\Users\simon\Downloads\P9\ghdl-axi-sim\axis-skidbuffer\ghdl\axi4-to-axis\wave.vcd" +[dumpfile_mtime] "Fri Apr 21 12:53:49 2023" +[dumpfile_size] 21480 +[savefile] "C:\Users\simon\Downloads\P9\ghdl-axi-sim\axis-skidbuffer\ghdl\axi4-to-axis\waveform.gtkw" +[timestart] 0 +[size] 1920 1057 +[pos] -1 -1 +*-25.000000 72400000 -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] 174 +[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.axi_converter_inst.s_axi_awvalid +tb_axis.axi_converter_inst.s_axi_awready +@22 +tb_axis.axi_converter_inst.s_axi_awaddr[19:0] +@28 +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 +@22 +[color] 2 +tb_axis.axi_converter_inst.s_axi_wdata[7:0] +@28 +[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 +tb_axis.axi_converter_inst.m_axis_tready +@22 +tb_axis.axi_converter_inst.m_axis_tdata[7:0] +@28 +tb_axis.axi_converter_inst.m_axis_tlast +[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/compile.bat b/ghdl/basic/compile.bat similarity index 82% rename from ghdl/compile.bat rename to ghdl/basic/compile.bat index 5e93a0a..cfa2e99 100644 --- a/ghdl/compile.bat +++ b/ghdl/basic/compile.bat @@ -9,11 +9,9 @@ del /Q *.cf & :: analyze ghdl -a skidbuffer.vhd -ghdl -a skidbuffer.vhd ghdl -a tb_skid.vhd :: elaborate ghdl -e skidbuffer -ghdl -e skidbuffer ghdl -e tb_skid :: run ghdl -r tb_skid --vcd=wave.vcd --stop-time=1us 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/tb_skid.vhd b/ghdl/basic/tb_skid.vhd similarity index 100% rename from ghdl/tb_skid.vhd rename to ghdl/basic/tb_skid.vhd diff --git a/ghdl/wave.vcd b/ghdl/basic/wave.vcd similarity index 100% rename from ghdl/wave.vcd rename to ghdl/basic/wave.vcd diff --git a/ghdl/waveform.gtkw b/ghdl/basic/waveform.gtkw similarity index 100% rename from ghdl/waveform.gtkw rename to ghdl/basic/waveform.gtkw From 4ccf8366791d1f26c6431f662f999730eab7d29f Mon Sep 17 00:00:00 2001 From: Simon Burkhardt Date: Mon, 24 Apr 2023 16:53:36 +0200 Subject: [PATCH 5/7] AXI4 to AXIS working initially --- README.md | 13 + ghdl/axi4-to-axis/axi4_to_axis.vhd | 143 +- ghdl/axi4-to-axis/tb_axis.vhd | 198 +- ghdl/axi4-to-axis/wave.vcd | 4934 ++++++++++++++++++---------- ghdl/axi4-to-axis/waveform.gtkw | 29 +- img/gtkwave_axi-to-axis.png | Bin 0 -> 232941 bytes 6 files changed, 3428 insertions(+), 1889 deletions(-) create mode 100644 img/gtkwave_axi-to-axis.png diff --git a/README.md b/README.md index 9181ebd..3021473 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,19 @@ Run in powershell: .\compile.bat ``` +## AXI4 Full to AXI-Stream converter + +Convert AXI4 write bursts to AXI-Slave protocol. + +- accepts AXI4 AW-channel handshake +- acknowledges successful transfer via `bresp` on B-channel after `axis_tlast` +- transfer AXI4 W-channel to AXI-S using skidbuffer +- supports `axis_tready` backpressure to `axi_awready` and `axi_wready` +- supports full throughput bandwidth with back-to-back burst transfer without wait cycles + +![img/gtkwave_axi-to-axis.png](img/gtkwave_axi-to-axis.png) + + # Acknowledgements https://zipcpu.com/blog/2019/05/22/skidbuffer.html diff --git a/ghdl/axi4-to-axis/axi4_to_axis.vhd b/ghdl/axi4-to-axis/axi4_to_axis.vhd index 91368cd..55f5942 100644 --- a/ghdl/axi4-to-axis/axi4_to_axis.vhd +++ b/ghdl/axi4-to-axis/axi4_to_axis.vhd @@ -218,31 +218,36 @@ architecture arch_imp of axi4_to_axis is m_data_o : out std_logic_vector((C_M_AXIS_DATA_WIDTH+(C_M_AXIS_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_M_AXIS_DATA_WIDTH-1 downto 0); - signal i_axis_data_strb : std_logic_vector(C_M_AXIS_DATA_WIDTH+(C_M_AXIS_DATA_WIDTH/8)-1 downto 0); + signal i_s_axis_data_strb : std_logic_vector(C_M_AXIS_DATA_WIDTH+(C_M_AXIS_DATA_WIDTH/8)-1 downto 0); signal i_s_axis_tstrb : std_logic_vector((C_M_AXIS_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_M_AXIS_DATA_WIDTH-1 downto 0); - signal o_axis_data_strb : std_logic_vector(C_M_AXIS_DATA_WIDTH+(C_M_AXIS_DATA_WIDTH/8)-1 downto 0); + signal o_m_axis_data_strb : std_logic_vector(C_M_AXIS_DATA_WIDTH+(C_M_AXIS_DATA_WIDTH/8)-1 downto 0); signal o_m_axis_tstrb : std_logic_vector((C_M_AXIS_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_s_axi_bresp : std_logic_vector(1 downto 0); - signal o_s_axi_bvalid : std_logic; - signal o_s_axi_bid : std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); - signal i_s_axi_bready : std_logic; + --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 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); @@ -297,12 +302,14 @@ begin 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_s_axi_bready <= S_AXI_BREADY; + i_axi_bready <= S_AXI_BREADY; i_axi_awid <= S_AXI_AWID; i_axi_awaddr <= S_AXI_AWADDR; @@ -324,9 +331,9 @@ begin 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_s_axi_bresp; - S_AXI_BVALID <= o_s_axi_bvalid; - S_AXI_BID <= o_s_axi_bid; + 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; @@ -336,53 +343,89 @@ begin S_AXI_WREADY <= o_axi_wready; -- combine strobe and data signals into single "data" channel - i_axis_data_strb <= i_s_axis_tdata & i_s_axis_tstrb; - o_m_axis_tdata <= o_axis_data_strb( (C_M_AXIS_DATA_WIDTH+(C_M_AXIS_DATA_WIDTH/8)) - 1 downto (C_M_AXIS_DATA_WIDTH/8) ); - o_m_axis_tstrb <= o_axis_data_strb( (C_M_AXIS_DATA_WIDTH/8) - 1 downto 0 ); + i_s_axis_data_strb <= i_s_axis_tdata & i_s_axis_tstrb; + o_m_axis_tdata <= o_m_axis_data_strb( (C_M_AXIS_DATA_WIDTH+(C_M_AXIS_DATA_WIDTH/8)) - 1 downto (C_M_AXIS_DATA_WIDTH/8) ); + o_m_axis_tstrb <= o_m_axis_data_strb( (C_M_AXIS_DATA_WIDTH/8) - 1 downto 0 ); - p_accept_aw : process(aclk) + p_axi_rx_flow_state : process(aclk) begin if rising_edge(aclk) then if aresetn = '0' then - o_axi_awready <= '1'; + 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 - if i_axi_awvalid = '1' then - o_axi_awready <= '0'; - temp_bid <= i_axi_awid; -- remember for BID in BRESP - else - o_axi_awready <= '1'; - end if; - end if; - end if; - end process; + -- 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; - p_bresp : process(aclk) - begin - if rising_edge(aclk) then - if aresetn = '0' then - o_s_axi_bvalid <= '0'; - o_s_axi_bresp <= (others => '0'); - o_s_axi_bid <= (others => '0'); - else - if o_s_axi_bvalid = '1' then -- waiting for ack from master - if i_s_axi_bready = '1' then -- master did ack - o_s_axi_bvalid <= '0'; -- BRESP complete - o_s_axi_bresp <= (others => '0'); - o_s_axi_bid <= (others => '0'); - end if; - else -- wait to generate a BRESP - -- TODO this if statement is won't work for non-burst transfers wher tlast is not used - if o_m_axis_tlast = '1' and i_m_axis_tready = '1' then - o_s_axi_bvalid <= '1'; - o_s_axi_bresp <= "00"; -- TODO is this 0b00 => "OKAY"? - o_s_axi_bid <= temp_bid; -- TODO write temp_bid in AW accept process - end if; - 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_M_AXIS_DATA_WIDTH+(C_M_AXIS_DATA_WIDTH/8)), @@ -395,12 +438,12 @@ begin 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, + 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_axis_data_strb + m_data_o => o_m_axis_data_strb ); end arch_imp; diff --git a/ghdl/axi4-to-axis/tb_axis.vhd b/ghdl/axi4-to-axis/tb_axis.vhd index c4eb6b1..9c14c6a 100644 --- a/ghdl/axi4-to-axis/tb_axis.vhd +++ b/ghdl/axi4-to-axis/tb_axis.vhd @@ -135,9 +135,10 @@ architecture bh of tb_axis is constant CLK_PERIOD: TIME := 5 ns; - signal sim_start_write : std_logic := '0'; + 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 sim_valid_data : std_logic := '0'; signal o_axis_tvalid : std_logic; signal o_axis_tdata : std_logic_vector(C_M_AXIS_DATA_WIDTH-1 downto 0); @@ -196,6 +197,7 @@ architecture bh of tb_axis is 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 @@ -218,8 +220,6 @@ begin wait; end process; - i_axis_tready <= '1'; -- TODO REMOVE - -- generate AW request p_aw_stimuli : process(clk) begin @@ -257,7 +257,14 @@ begin o_axi_awsize <= "110"; -- 64 bytes o_axi_awburst <= "01"; -- INCR o_axi_awvalid <= '1'; - sim_valid_data <= '0'; + --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; @@ -273,41 +280,58 @@ begin o_axi_wstrb <= (others => '0'); sim_data <= (others => '0'); o_axi_wlast <= '0'; + o_axi_wvalid <= '0'; else - if sim_valid_data = '1' then -- OK from a valid AW handshake - if i_axi_wready = '1' then -- wready from slave - if unsigned(o_axi_wdata) = 63 then - o_axi_wlast <= '1'; - else - o_axi_wlast <= '0'; - end if; - - if unsigned(o_axi_wdata) = 64 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); + 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(sim_data) = 64 then - sim_data(C_S_AXI_DATA_WIDTH-1 downto 1) <= (others => '0'); - sim_data(0) <= '1'; + + 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 - sim_data <= std_logic_vector(unsigned(sim_data) + 1); + 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; - else - o_axi_wdata <= o_axi_wdata; - sim_data <= sim_data; - end if; - o_axi_wvalid <= '1'; - o_axi_wstrb <= "1"; + -- end if; else o_axi_wvalid <= '0'; o_axi_wstrb <= "0"; @@ -319,19 +343,113 @@ begin 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_stimuli_tready : process(clk) + p_slave_tready : process(clk) begin if rising_edge(clk) then if rst_n = '0' then - sim_start_write <= '0'; + i_axis_tready <= '0'; else - if unsigned(clk_count) = 3 then - sim_start_write <= '1'; + if sim_start_ready = '1' then + i_axis_tready <= '1'; + else + i_axis_tready <= '0'; end if; - if unsigned(clk_count) = 4 then + 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; diff --git a/ghdl/axi4-to-axis/wave.vcd b/ghdl/axi4-to-axis/wave.vcd index f5a89f6..8bf473b 100644 --- a/ghdl/axi4-to-axis/wave.vcd +++ b/ghdl/axi4-to-axis/wave.vcd @@ -1,5 +1,5 @@ $date - Fri Apr 21 15:21:41 2023 + Mon Apr 24 16:02:53 2023 $end $version GHDL v0 @@ -15,131 +15,132 @@ $scope module numeric_std $end $upscope $end $scope module tb_axis $end $var reg 1 ! sim_start_write $end -$var reg 8 " sim_data[7:0] $end +$var reg 1 " sim_start_ready $end $var reg 1 # sim_valid_data $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 / o_axi_awburst[1:0] $end -$var reg 1 0 o_axi_awlock $end -$var reg 4 1 o_axi_awcache[3:0] $end -$var reg 3 2 o_axi_awprot[2:0] $end -$var reg 4 3 o_axi_awqos[3:0] $end -$var reg 4 4 o_axi_awregion[3:0] $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 5 o_axi_awvalid $end -$var reg 1 6 i_axi_awready $end -$var reg 8 7 o_axi_wdata[7:0] $end -$var reg 1 8 o_axi_wstrb[0:0] $end -$var reg 1 9 o_axi_wlast $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 +$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 @ o_axi_arid[2:0] $end -$var reg 8 A o_axi_araddr[7:0] $end -$var reg 8 B o_axi_arlen[7:0] $end -$var reg 3 C o_axi_arsize[2:0] $end -$var reg 2 D o_axi_arburst[1:0] $end -$var reg 1 E o_axi_arlock $end -$var reg 4 F o_axi_arcache[3:0] $end -$var reg 3 G o_axi_arprot[2:0] $end -$var reg 4 H o_axi_arqos[3:0] $end -$var reg 4 I o_axi_arregion[3:0] $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 J o_axi_arvalid $end -$var reg 1 K i_axi_arready $end -$var reg 3 L i_axi_rid[2:0] $end -$var reg 8 M i_axi_rdata[7:0] $end -$var reg 2 N i_axi_rresp[1:0] $end -$var reg 1 O i_axi_rlast $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 P i_axi_rvalid $end -$var reg 1 Q o_axi_rready $end -$var reg 8 R clk_count[7:0] $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 S axis_aclk $end -$var reg 1 T axis_aresetn $end -$var reg 3 U s_axi_awid[2:0] $end -$var reg 8 V s_axi_awaddr[7:0] $end -$var reg 8 W s_axi_awlen[7:0] $end -$var reg 3 X s_axi_awsize[2:0] $end -$var reg 2 Y s_axi_awburst[1:0] $end -$var reg 1 Z 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 +$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 _ s_axi_awvalid $end -$var reg 1 ` s_axi_awready $end -$var reg 8 a s_axi_wdata[7:0] $end -$var reg 1 b s_axi_wstrb[0:0] $end -$var reg 1 c s_axi_wlast $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 d s_axi_wvalid $end -$var reg 1 e s_axi_wready $end -$var reg 3 f s_axi_bid[2:0] $end -$var reg 2 g s_axi_bresp[1:0] $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 h s_axi_bvalid $end -$var reg 1 i s_axi_bready $end -$var reg 3 j s_axi_arid[2:0] $end -$var reg 8 k s_axi_araddr[7:0] $end -$var reg 8 l s_axi_arlen[7:0] $end -$var reg 3 m s_axi_arsize[2:0] $end -$var reg 2 n s_axi_arburst[1:0] $end -$var reg 1 o s_axi_arlock $end -$var reg 4 p s_axi_arcache[3:0] $end -$var reg 3 q s_axi_arprot[2:0] $end -$var reg 4 r s_axi_arqos[3:0] $end -$var reg 4 s s_axi_arregion[3:0] $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 t s_axi_arvalid $end -$var reg 1 u s_axi_arready $end -$var reg 3 v s_axi_rid[2:0] $end -$var reg 8 w s_axi_rdata[7:0] $end -$var reg 2 x s_axi_rresp[1:0] $end -$var reg 1 y s_axi_rlast $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 z 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 -$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_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 ." o_axis_data_strb[8:0] $end -$var reg 1 /" o_m_axis_tstrb[0:0] $end -$var reg 1 0" o_m_axis_tlast $end -$var reg 1 1" i_m_axis_tready $end -$var reg 2 2" o_s_axi_bresp[1:0] $end -$var reg 1 3" o_s_axi_bvalid $end -$var reg 3 4" o_s_axi_bid[2:0] $end -$var reg 1 5" i_s_axi_bready $end -$var reg 3 6" temp_bid[2:0] $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 @@ -211,120 +212,120 @@ $upscope $end $enddefinitions $end #0 0! -bUUUUUUUU " +0" 0# -U$ -bUUUUUUUU % -bU & -U' -1( -1) -0* -bUUU + -bUUUUUUUU , +bUUUUUUUU $ +U% +bUUUUUUUU & +bU ' +U( +0) +1* +0+ +bUUU , bUUUUUUUU - -bUUU . -bUU / -U0 -bUUUU 1 -bUUU 2 -bUUUU 3 +bUUUUUUUU . +bUUU / +bUU 0 +U1 +bUUUU 2 +bUUU 3 bUUUU 4 -U5 +bUUUU 5 U6 -bUUUUUUUU 7 -bU 8 -U9 +U7 +bUUUUUUUU 8 +bU 9 U: U; -bUUU < -bUU = -U> +U< +bUUU = +bUU > U? -bUUU @ -bUUUUUUUU A +U@ +bUUU A bUUUUUUUU B -bUUU C -bUU D -UE -bUUUU F -bUUU G -bUUUU H +bUUUUUUUU C +bUUU D +bUU E +UF +bUUUU G +bUUU H bUUUU I -UJ +bUUUU J UK -bUUU L -bUUUUUUUU M -bUU N -UO +UL +bUUU M +bUUUUUUUU N +bUU O UP UQ -b00000000 R -1S -0T -bUUU U -bUUUUUUUU V -bUUUUUUUU W -bUUU X -bUU Y -UZ -bUUUU [ -bUUU \ +UR +b00000000 S +b00000000 T +1U +0V +bUUU W +bUUUUUUUU X +bUUUUUUUU Y +bUUU Z +bUU [ +U\ bUUUU ] -bUUUU ^ -U_ -U` -bUUUUUUUU a -bU b -Uc -Ud +bUUU ^ +bUUUU _ +bUUUU ` +Ua +Ub +bUUUUUUUU c +bU d Ue -bUUU f -bUU g -Uh -Ui -bUUU j -bUUUUUUUU k -bUUUUUUUU l -bUUU m -bUU n -Uo -bUUUU p -bUUU q +Uf +Ug +bUUU h +bUU i +Uj +Uk +bUUU l +bUUUUUUUU m +bUUUUUUUU n +bUUU o +bUU p +Uq bUUUU r -bUUUU s -Ut -Uu -bUUU v -bUUUUUUUU w -bUU x -Uy -Uz +bUUU s +bUUUU t +bUUUU u +Uv +Uw +bUUU x +bUUUUUUUU y +bUU z U{ U| -bUUUUUUUU } -bU !" -U"" -1#" -1$" +U} +U!" +bUUUUUUUU "" +bU #" +U$" 0%" -U&" -bUUUUUUUU '" -bUUUUUUUUU (" -bU )" -U*" -U+" +1&" +0'" +U(" +bUUUUUUUU )" +bUUUUUUUUU *" +bU +" U," -bUUUUUUUU -" -bUUUUUUUUU ." -bU /" -U0" -11" -bUU 2" -U3" +U-" +U." +bUUUUUUUU /" +bUUUUUUUUU 0" +bU 1" +U2" +03" bUUU 4" U5" -bUUU 6" +bUU 6" bUUU 7" bUUUUUUUU 8" bUUUUUUUU 9" @@ -372,7 +373,7 @@ Ub" bUUUUUUUUU c" Ud" Ue" -1f" +0f" bUUUUUUUUU g" bUUUUUUUUU h" Ui" @@ -383,74 +384,79 @@ Um" bUUUUUUUUU n" Uo" #2500000 -0) -0S -0$" +0* +0U +0&" 0^" #5000000 -b00000000 " -0$ -b00000000 % -b0 & -0' -1) -b000 + -b00000000 , +b00000000 $ +0% +b00000000 & +b0 ' +0( +1* +b000 , b00000000 - -b000 . -b00 / -00 -b0000 1 -b000 2 -b0000 3 +b00000000 . +b000 / +b00 0 +01 +b0000 2 +b000 3 b0000 4 -05 -16 -b00000000 7 -b0 8 -09 -b000 < -b00 = -0> -b00000001 R -1S -b000 U -b00000000 V -b00000000 W -b000 X -b00 Y -0Z -b0000 [ -b000 \ +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 ] -b0000 ^ -0_ -1` -b00000000 a -b0 b -0c -Ue -b000 f -b00 g -0h -0| -b00000000 } -b0 !" -0"" -1$" -b00000000 '" -b000000000 (" -b0 )" -0*" -0+" +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," -b00000000 -" -b000000000 ." -b0 /" -00" -b00 2" -03" -b000 4" +0-" +0." +b00000000 /" +b000000000 0" +b0 1" +02" +05" +b00 6" b000 7" b00000000 8" b00000000 9" @@ -466,7 +472,14 @@ b0000 @" b00000000 C" b0 D" 0E" +0F" +0G" +b000 H" +b00 I" +0J" +1K" 1^" +0`" 0a" 0b" b000000000 c" @@ -482,108 +495,114 @@ b000000000 l" b000000000 n" 0o" #6250000 -1* -1T -1%" +1+ +1V +1'" 1_" #7500000 -0) -0S -0$" +0* +0U +0&" 0^" #10000000 -U$ -1) -0: -b00000010 R -1S -0d -Ue -U| -1$" -0&" -1+" -U," -0F" +1" +1* +b00000010 S +1U +1&" +b01 6" 1^" -0`" -1b" -Ud" -Uj" -1k" #12500000 -0) -0S -0$" +0* +0U +0&" 0^" #15000000 1! -0$ 1) -b00000011 R -1S -0| -1$" -0," +1* +b00000011 S +b00000001 T +1U +1%" +1&" +13" 1^" -0d" -0j" +1f" #17500000 -0) -0S -0$" +0* +0U +0&" 0^" #20000000 -0! -1) -b101 + -b01000010 , -b00111111 - -b110 . -b01 / -15 -b00000100 R -1S -b101 U -b01000010 V -b00111111 W -b110 X -b01 Y -1_ -1$" +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) -0S -0$" +0* +0U +0&" 0^" #25000000 +0! 1# -1) -b000 + -b00000000 , +b00000001 $ +1* +b000 , b00000000 - -b000 . -b00 / -05 +b00000000 . +b000 / +b00 0 06 -b00000101 R -1S -b000 U -b00000000 V -b00000000 W -b000 X -b00 Y -0_ -0` -1$" -b101 6" +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" @@ -591,2176 +610,3519 @@ b000 :" b00 ;" 0A" 0B" +b00000001 C" +b1 D" +1F" +b101 H" 1^" +1`" +b000000011 c" #27500000 -0) -0S -0$" +0* +0U +0&" 0^" #30000000 -1) -16 -b1 8 -1: -b00000110 R -1S -1` -b1 b -1d -1$" +b00000010 $ +1% +b00000001 & +b1 ' +1* +17 +b00000010 8 +b00000110 S +1U +1b +b00000010 c +1!" +b00000001 "" +b1 #" 1&" -b000000001 (" -b1 )" +b00000010 )" +b000000101 *" +1." +b00000001 /" +b000000011 0" +b1 1" +b10 6" 1B" -b1 D" -1F" +b00000010 C" 1^" -1`" -b000000001 c" +b000000101 c" +1d" +b000000011 g" +b000000011 h" +1j" +b000000011 l" +b000000011 n" #32500000 -0) -0S -0$" +0* +0U +0&" 0^" #35000000 -1$ -b1 & -1) -b00000111 R -1S -1| -b1 !" -1$" -1," -b000000001 ." -b1 /" -1^" -1d" -b000000001 g" -b000000001 h" -1j" -b000000001 l" -b000000001 n" +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) -0S -0$" +0* +0U +0&" 0^" #40000000 -1) -b00001000 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #45000000 -1) -b00001001 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #50000000 -1) -b00001010 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #55000000 -1) -b00001011 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #60000000 -1) -b00001100 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #65000000 -1) -b00001101 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #70000000 -1) -b00001110 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #75000000 -1) -b00001111 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #80000000 -1) -b00010000 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #85000000 -1) -b00010001 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #90000000 -1) -b00010010 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #95000000 -1) -b00010011 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #100000000 -1) -b00010100 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #105000000 -1) -b00010101 R -1S +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) -0S -0$" +0* +0U +0&" 0^" #110000000 -1) -b00010110 R -1S -1$" -1^" -#112500000 -0) -0S +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 -1) -b00010111 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #120000000 -1) -b00011000 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #125000000 -1) -b00011001 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #130000000 -1) -b00011010 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #135000000 -1) -b00011011 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #140000000 -1) -b00011100 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #145000000 -1) -b00011101 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #150000000 -1) -b00011110 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #155000000 -1) -b00011111 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #160000000 -1) -b00100000 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #165000000 -1) -b00100001 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #170000000 -1) -b00100010 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #175000000 -1) -b00100011 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #180000000 -1) -b00100100 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #185000000 -1) -b00100101 R -1S +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) -0S -0$" +0* +0U +0&" 0^" #190000000 -1) -b00100110 R -1S -1$" +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) -0S -0$" +0* +0U +0&" 0^" #195000000 -1) -b00100111 R -1S -1$" +1* +0? +0@ +b00100111 S +1U +0j +0k +1&" +b01 6" +0J" +0K" 1^" #197500000 -0) -0S -0$" +0* +0U +0&" 0^" #200000000 -1) -b00101000 R -1S -1$" +1* +1@ +b00101000 S +1U +1k +1&" +1K" 1^" #202500000 -0) -0S -0$" +0* +0U +0&" 0^" #205000000 -1) -b00101001 R -1S -1$" +1* +b00101001 S +1U +1&" 1^" #207500000 -0) -0S -0$" +0* +0U +0&" 0^" #210000000 -1) -b00101010 R -1S -1$" +1* +b00101010 S +1U +1&" 1^" #212500000 -0) -0S -0$" +0* +0U +0&" 0^" #215000000 -1) -b00101011 R -1S -1$" +1* +b00101011 S +1U +1&" 1^" #217500000 -0) -0S -0$" +0* +0U +0&" 0^" #220000000 -1) -b00101100 R -1S -1$" +1* +b00101100 S +1U +1&" 1^" #222500000 -0) -0S -0$" +0* +0U +0&" 0^" #225000000 -1) -b00101101 R -1S -1$" +1* +b00101101 S +1U +1&" 1^" #227500000 -0) -0S -0$" +0* +0U +0&" 0^" #230000000 -1) -b00101110 R -1S -1$" +1! +1* +b00101110 S +b00000001 T +1U +1&" 1^" #232500000 -0) -0S -0$" +0* +0U +0&" 0^" #235000000 -1) -b00101111 R -1S -1$" +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) -0S -0$" +0* +0U +0&" 0^" #240000000 -1) -b00110000 R -1S -1$" +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) -0S -0$" +0* +0U +0&" 0^" #245000000 -1) -b00110001 R -1S -1$" +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) -0S -0$" +0* +0U +0&" 0^" #250000000 -1) -b00110010 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #255000000 -1) -b00110011 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #260000000 -1) -b00110100 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #265000000 -1) -b00110101 R -1S -1$" -1^" -#267500000 +b00000110 $ +b00000101 & 0) -0S -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 -1) -b00110110 R -1S -1$" +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) -0S -0$" +0* +0U +0&" 0^" #275000000 -1) -b00110111 R -1S -1$" +1* +b00110111 S +1U +1&" 1^" #277500000 -0) -0S -0$" +0* +0U +0&" 0^" #280000000 -1) -b00111000 R -1S -1$" +1! +1* +b00111000 S +b00000010 T +1U +1&" 1^" #282500000 -0) -0S -0$" +0* +0U +0&" 0^" #285000000 -1) -b00111001 R -1S -1$" +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) -0S -0$" +0* +0U +0&" 0^" #290000000 -1) -b00111010 R -1S -1$" +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) -0S -0$" +0* +0U +0&" 0^" #295000000 -1) -b00111011 R -1S -1$" +1* +b00111011 S +1U +1&" +b11 6" 1^" #297500000 -0) -0S -0$" +0* +0U +0&" 0^" #300000000 -1) -b00111100 R -1S -1$" +1* +b00111100 S +1U +1&" 1^" #302500000 -0) -0S -0$" +0* +0U +0&" 0^" #305000000 -1) -b00111101 R -1S -1$" +1* +b00111101 S +1U +1&" 1^" #307500000 -0) -0S -0$" +0* +0U +0&" 0^" #310000000 -1) -b00111110 R -1S -1$" +1* +b00111110 S +1U +1&" 1^" #312500000 -0) -0S -0$" +0* +0U +0&" 0^" #315000000 -1) -b00111111 R -1S -1$" +1* +b00111111 S +1U +1&" 1^" #317500000 -0) -0S -0$" +0* +0U +0&" 0^" #320000000 -1) -b01000000 R -1S -1$" +1* +b01000000 S +1U +1&" 1^" #322500000 -0) -0S -0$" +0* +0U +0&" 0^" #325000000 -1) -b01000001 R -1S -1$" +1* +b01000001 S +1U +1&" 1^" #327500000 -0) -0S -0$" +0* +0U +0&" 0^" #330000000 -1) -b01000010 R -1S -1$" +1* +b01000010 S +1U +1&" 1^" #332500000 -0) -0S -0$" +0* +0U +0&" 0^" #335000000 -1) -b01000011 R -1S -1$" +1* +b01000011 S +1U +1&" 1^" #337500000 -0) -0S -0$" +0* +0U +0&" 0^" #340000000 -1) -b01000100 R -1S -1$" +1* +b01000100 S +1U +1&" 1^" #342500000 -0) -0S -0$" +0* +0U +0&" 0^" #345000000 -1) -b01000101 R -1S -1$" +1* +b01000101 S +1U +1&" 1^" #347500000 -0) -0S -0$" +0* +0U +0&" 0^" #350000000 -1) -b01000110 R -1S -1$" +1" +1* +b01000110 S +1U +1&" 1^" #352500000 -0) -0S -0$" +0* +0U +0&" 0^" #355000000 1) -b01000111 R -1S -1$" +1* +b01000111 S +1U +1%" +1&" +13" 1^" +1f" #357500000 -0) -0S -0$" +0* +0U +0&" 0^" #360000000 -1) -b01001000 R -1S -1$" +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) -0S -0$" +0* +0U +0&" 0^" #365000000 -1) -b01001001 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #370000000 -1) -b01001010 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #375000000 -1) -b01001011 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #380000000 -1) -b01001100 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #385000000 -1) -b01001101 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #390000000 -1) -b01001110 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #395000000 -1) -b01001111 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #400000000 -1) -b01010000 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #405000000 -1) -b01010001 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #410000000 -1) -b01010010 R -1S +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) -0S -0$" +0* +0U +0&" 0^" #415000000 -1) -b01010011 R -1S -1$" +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) -0S -0$" +0* +0U +0&" 0^" #420000000 -1) -b01010100 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #425000000 -1) -b01010101 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #430000000 -1) -b01010110 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #435000000 -1) -b01010111 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #440000000 -1) -b01011000 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #445000000 -1) -b01011001 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #450000000 -1) -b01011010 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #455000000 -1) -b01011011 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #460000000 -1) -b01011100 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #465000000 -1) -b01011101 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #470000000 -1) -b01011110 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #475000000 -1) -b01011111 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #480000000 -1) -b01100000 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #485000000 -1) -b01100001 R -1S -1$" -1^" +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) -0S -0$" +0* +0U +0&" 0^" #490000000 -1) -b01100010 R -1S +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) -0S -0$" +0* +0U +0&" 0^" #495000000 -1) -b01100011 R -1S -1$" +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) -0S -0$" +0* +0U +0&" 0^" #500000000 -1) -b01100100 R -1S -1$" +1* +0? +0@ +b01100100 S +1U +0j +0k +1&" +b01 6" +0J" +0K" 1^" #502500000 -0) -0S -0$" +0* +0U +0&" 0^" #505000000 -1) -b01100101 R -1S -1$" +1* +1@ +b01100101 S +1U +1k +1&" +1K" 1^" #507500000 -0) -0S -0$" +0* +0U +0&" 0^" #510000000 -1) -b01100110 R -1S -1$" +1* +b01100110 S +1U +1&" 1^" #512500000 -0) -0S -0$" +0* +0U +0&" 0^" #515000000 -1) -b01100111 R -1S -1$" +1* +b01100111 S +1U +1&" 1^" #517500000 -0) -0S -0$" +0* +0U +0&" 0^" #520000000 -1) -b01101000 R -1S -1$" +1* +b01101000 S +1U +1&" 1^" #522500000 -0) -0S -0$" +0* +0U +0&" 0^" #525000000 -1) -b01101001 R -1S -1$" +1* +b01101001 S +1U +1&" 1^" #527500000 -0) -0S -0$" +0* +0U +0&" 0^" #530000000 -1) -b01101010 R -1S -1$" +1* +b01101010 S +1U +1&" 1^" #532500000 -0) -0S -0$" +0* +0U +0&" 0^" #535000000 -1) -b01101011 R -1S -1$" +1* +b01101011 S +1U +1&" 1^" #537500000 -0) -0S -0$" +0* +0U +0&" 0^" #540000000 -1) -b01101100 R -1S -1$" +1* +b01101100 S +1U +1&" 1^" #542500000 -0) -0S -0$" +0* +0U +0&" 0^" #545000000 -1) -b01101101 R -1S -1$" +1* +b01101101 S +1U +1&" 1^" #547500000 -0) -0S -0$" +0* +0U +0&" 0^" #550000000 -1) -b01101110 R -1S -1$" +1* +b01101110 S +1U +1&" 1^" #552500000 -0) -0S -0$" +0* +0U +0&" 0^" #555000000 -1) -b01101111 R -1S -1$" +1* +b01101111 S +1U +1&" 1^" #557500000 -0) -0S -0$" +0* +0U +0&" 0^" #560000000 -1) -b01110000 R -1S -1$" +1* +b01110000 S +1U +1&" 1^" #562500000 -0) -0S -0$" +0* +0U +0&" 0^" #565000000 -1) -b01110001 R -1S -1$" +1* +b01110001 S +1U +1&" 1^" #567500000 -0) -0S -0$" +0* +0U +0&" 0^" #570000000 -1) -b01110010 R -1S -1$" +1* +b01110010 S +1U +1&" 1^" #572500000 -0) -0S -0$" +0* +0U +0&" 0^" #575000000 -1) -b01110011 R -1S -1$" +1* +b01110011 S +1U +1&" 1^" #577500000 -0) -0S -0$" +0* +0U +0&" 0^" #580000000 -1) -b01110100 R -1S -1$" +1* +b01110100 S +1U +1&" 1^" #582500000 -0) -0S -0$" +0* +0U +0&" 0^" #585000000 -1) -b01110101 R -1S -1$" +1* +b01110101 S +1U +1&" 1^" #587500000 -0) -0S -0$" +0* +0U +0&" 0^" #590000000 -1) -b01110110 R -1S -1$" +1* +b01110110 S +1U +1&" 1^" #592500000 -0) -0S -0$" +0* +0U +0&" 0^" #595000000 -1) -b01110111 R -1S -1$" +1* +b01110111 S +1U +1&" 1^" #597500000 -0) -0S -0$" +0* +0U +0&" 0^" #600000000 -1) -b01111000 R -1S -1$" +1* +b01111000 S +1U +1&" 1^" #602500000 -0) -0S -0$" +0* +0U +0&" 0^" #605000000 -1) -b01111001 R -1S -1$" +1* +b01111001 S +1U +1&" 1^" #607500000 -0) -0S -0$" +0* +0U +0&" 0^" #610000000 -1) -b01111010 R -1S -1$" +1* +b01111010 S +1U +1&" 1^" #612500000 -0) -0S -0$" +0* +0U +0&" 0^" #615000000 -1) -b01111011 R -1S -1$" +1* +b01111011 S +1U +1&" 1^" #617500000 -0) -0S -0$" +0* +0U +0&" 0^" #620000000 -1) -b01111100 R -1S -1$" +1* +b01111100 S +1U +1&" 1^" #622500000 -0) -0S -0$" +0* +0U +0&" 0^" #625000000 -1) -b01111101 R -1S -1$" +1* +b01111101 S +1U +1&" 1^" #627500000 -0) -0S -0$" +0* +0U +0&" 0^" #630000000 -1) -b01111110 R -1S -1$" +1* +b01111110 S +1U +1&" 1^" #632500000 -0) -0S -0$" +0* +0U +0&" 0^" #635000000 -1) -b01111111 R -1S -1$" +1* +b01111111 S +1U +1&" 1^" #637500000 -0) -0S -0$" +0* +0U +0&" 0^" #640000000 -1) -b10000000 R -1S -1$" +1* +b10000000 S +1U +1&" 1^" #642500000 -0) -0S -0$" +0* +0U +0&" 0^" #645000000 -1) -b10000001 R -1S -1$" +1* +b10000001 S +1U +1&" 1^" #647500000 -0) -0S -0$" +0* +0U +0&" 0^" #650000000 -1) -b10000010 R -1S -1$" +1* +b10000010 S +1U +1&" 1^" #652500000 -0) -0S -0$" +0* +0U +0&" 0^" #655000000 -1) -b10000011 R -1S -1$" +1* +b10000011 S +1U +1&" 1^" #657500000 -0) -0S -0$" +0* +0U +0&" 0^" #660000000 -1) -b10000100 R -1S -1$" +1* +b10000100 S +1U +1&" 1^" #662500000 -0) -0S -0$" +0* +0U +0&" 0^" #665000000 -1) -b10000101 R -1S -1$" +1* +b10000101 S +1U +1&" 1^" #667500000 -0) -0S -0$" +0* +0U +0&" 0^" #670000000 -1) -b10000110 R -1S -1$" +1* +b10000110 S +1U +1&" 1^" #672500000 -0) -0S -0$" +0* +0U +0&" 0^" #675000000 -1) -b10000111 R -1S -1$" +1* +b10000111 S +1U +1&" 1^" #677500000 -0) -0S -0$" +0* +0U +0&" 0^" #680000000 -1) -b10001000 R -1S -1$" +1* +b10001000 S +1U +1&" 1^" #682500000 -0) -0S -0$" +0* +0U +0&" 0^" #685000000 -1) -b10001001 R -1S -1$" +1* +b10001001 S +1U +1&" 1^" #687500000 -0) -0S -0$" +0* +0U +0&" 0^" #690000000 -1) -b10001010 R -1S -1$" +1* +b10001010 S +1U +1&" 1^" #692500000 -0) -0S -0$" +0* +0U +0&" 0^" #695000000 -1) -b10001011 R -1S -1$" +1* +b10001011 S +1U +1&" 1^" #697500000 -0) -0S -0$" +0* +0U +0&" 0^" #700000000 -1) -b10001100 R -1S -1$" +1* +b10001100 S +1U +1&" 1^" #702500000 -0) -0S -0$" +0* +0U +0&" 0^" #705000000 -1) -b10001101 R -1S -1$" +1* +b10001101 S +1U +1&" 1^" #707500000 -0) -0S -0$" +0* +0U +0&" 0^" #710000000 -1) -b10001110 R -1S -1$" +1* +b10001110 S +1U +1&" 1^" #712500000 -0) -0S -0$" +0* +0U +0&" 0^" #715000000 -1) -b10001111 R -1S -1$" +1* +b10001111 S +1U +1&" 1^" #717500000 -0) -0S -0$" +0* +0U +0&" 0^" #720000000 -1) -b10010000 R -1S -1$" +1* +b10010000 S +1U +1&" 1^" #722500000 -0) -0S -0$" +0* +0U +0&" 0^" #725000000 -1) -b10010001 R -1S -1$" +1* +b10010001 S +1U +1&" 1^" #727500000 -0) -0S -0$" +0* +0U +0&" 0^" #730000000 -1) -b10010010 R -1S -1$" +1* +b10010010 S +1U +1&" 1^" #732500000 -0) -0S -0$" +0* +0U +0&" 0^" #735000000 -1) -b10010011 R -1S -1$" +1* +b10010011 S +1U +1&" 1^" #737500000 -0) -0S -0$" +0* +0U +0&" 0^" #740000000 -1) -b10010100 R -1S -1$" +1* +b10010100 S +1U +1&" 1^" #742500000 -0) -0S -0$" +0* +0U +0&" 0^" #745000000 -1) -b10010101 R -1S -1$" +1* +b10010101 S +1U +1&" 1^" #747500000 -0) -0S -0$" +0* +0U +0&" 0^" #750000000 -1) -b10010110 R -1S -1$" +1* +b10010110 S +1U +1&" 1^" #752500000 -0) -0S -0$" +0* +0U +0&" 0^" #755000000 -1) -b10010111 R -1S -1$" +1* +b10010111 S +1U +1&" 1^" #757500000 -0) -0S -0$" +0* +0U +0&" 0^" #760000000 -1) -b10011000 R -1S -1$" +1* +b10011000 S +1U +1&" 1^" #762500000 -0) -0S -0$" +0* +0U +0&" 0^" #765000000 -1) -b10011001 R -1S -1$" +1* +b10011001 S +1U +1&" 1^" #767500000 -0) -0S -0$" +0* +0U +0&" 0^" #770000000 -1) -b10011010 R -1S -1$" +1* +b10011010 S +1U +1&" 1^" #772500000 -0) -0S -0$" +0* +0U +0&" 0^" #775000000 -1) -b10011011 R -1S -1$" +1* +b10011011 S +1U +1&" 1^" #777500000 -0) -0S -0$" +0* +0U +0&" 0^" #780000000 -1) -b10011100 R -1S -1$" +1* +b10011100 S +1U +1&" 1^" #782500000 -0) -0S -0$" +0* +0U +0&" 0^" #785000000 -1) -b10011101 R -1S -1$" +1* +b10011101 S +1U +1&" 1^" #787500000 -0) -0S -0$" +0* +0U +0&" 0^" #790000000 -1) -b10011110 R -1S -1$" +1* +b10011110 S +1U +1&" 1^" #792500000 -0) -0S -0$" +0* +0U +0&" 0^" #795000000 -1) -b10011111 R -1S -1$" +1* +b10011111 S +1U +1&" 1^" #797500000 -0) -0S -0$" +0* +0U +0&" 0^" #800000000 -1) -b10100000 R -1S -1$" +1* +b10100000 S +1U +1&" 1^" #802500000 -0) -0S -0$" +0* +0U +0&" 0^" #805000000 -1) -b10100001 R -1S -1$" +1* +b10100001 S +1U +1&" 1^" #807500000 -0) -0S -0$" +0* +0U +0&" 0^" #810000000 -1) -b10100010 R -1S -1$" +1* +b10100010 S +1U +1&" 1^" #812500000 -0) -0S -0$" +0* +0U +0&" 0^" #815000000 -1) -b10100011 R -1S -1$" +1* +b10100011 S +1U +1&" 1^" #817500000 -0) -0S -0$" +0* +0U +0&" 0^" #820000000 -1) -b10100100 R -1S -1$" +1* +b10100100 S +1U +1&" 1^" #822500000 -0) -0S -0$" +0* +0U +0&" 0^" #825000000 -1) -b10100101 R -1S -1$" +1* +b10100101 S +1U +1&" 1^" #827500000 -0) -0S -0$" +0* +0U +0&" 0^" #830000000 -1) -b10100110 R -1S -1$" +1* +b10100110 S +1U +1&" 1^" #832500000 -0) -0S -0$" +0* +0U +0&" 0^" #835000000 -1) -b10100111 R -1S -1$" +1* +b10100111 S +1U +1&" 1^" #837500000 -0) -0S -0$" +0* +0U +0&" 0^" #840000000 -1) -b10101000 R -1S -1$" +1* +b10101000 S +1U +1&" 1^" #842500000 -0) -0S -0$" +0* +0U +0&" 0^" #845000000 -1) -b10101001 R -1S -1$" +1* +b10101001 S +1U +1&" 1^" #847500000 -0) -0S -0$" +0* +0U +0&" 0^" #850000000 -1) -b10101010 R -1S -1$" +1* +b10101010 S +1U +1&" 1^" #852500000 -0) -0S -0$" +0* +0U +0&" 0^" #855000000 -1) -b10101011 R -1S -1$" +1* +b10101011 S +1U +1&" 1^" #857500000 -0) -0S -0$" +0* +0U +0&" 0^" #860000000 -1) -b10101100 R -1S -1$" +1* +b10101100 S +1U +1&" 1^" #862500000 -0) -0S -0$" +0* +0U +0&" 0^" #865000000 -1) -b10101101 R -1S -1$" +1* +b10101101 S +1U +1&" 1^" #867500000 -0) -0S -0$" +0* +0U +0&" 0^" #870000000 -1) -b10101110 R -1S -1$" +1* +b10101110 S +1U +1&" 1^" #872500000 -0) -0S -0$" +0* +0U +0&" 0^" #875000000 -1) -b10101111 R -1S -1$" +1* +b10101111 S +1U +1&" 1^" #877500000 -0) -0S -0$" +0* +0U +0&" 0^" #880000000 -1) -b10110000 R -1S -1$" +1* +b10110000 S +1U +1&" 1^" #882500000 -0) -0S -0$" +0* +0U +0&" 0^" #885000000 -1) -b10110001 R -1S -1$" +1* +b10110001 S +1U +1&" 1^" #887500000 -0) -0S -0$" +0* +0U +0&" 0^" #890000000 -1) -b10110010 R -1S -1$" +1* +b10110010 S +1U +1&" 1^" #892500000 -0) -0S -0$" +0* +0U +0&" 0^" #895000000 -1) -b10110011 R -1S -1$" +1* +b10110011 S +1U +1&" 1^" #897500000 -0) -0S -0$" +0* +0U +0&" 0^" #900000000 -1) -b10110100 R -1S -1$" +1* +b10110100 S +1U +1&" 1^" #902500000 -0) -0S -0$" +0* +0U +0&" 0^" #905000000 -1) -b10110101 R -1S -1$" +1* +b10110101 S +1U +1&" 1^" #907500000 -0) -0S -0$" +0* +0U +0&" 0^" #910000000 -1) -b10110110 R -1S -1$" +1* +b10110110 S +1U +1&" 1^" #912500000 -0) -0S -0$" +0* +0U +0&" 0^" #915000000 -1) -b10110111 R -1S -1$" +1* +b10110111 S +1U +1&" 1^" #917500000 -0) -0S -0$" +0* +0U +0&" 0^" #920000000 -1) -b10111000 R -1S -1$" +1* +b10111000 S +1U +1&" 1^" #922500000 -0) -0S -0$" +0* +0U +0&" 0^" #925000000 -1) -b10111001 R -1S -1$" +1* +b10111001 S +1U +1&" 1^" #927500000 -0) -0S -0$" +0* +0U +0&" 0^" #930000000 -1) -b10111010 R -1S -1$" +1* +b10111010 S +1U +1&" 1^" #932500000 -0) -0S -0$" +0* +0U +0&" 0^" #935000000 -1) -b10111011 R -1S -1$" +1* +b10111011 S +1U +1&" 1^" #937500000 -0) -0S -0$" +0* +0U +0&" 0^" #940000000 -1) -b10111100 R -1S -1$" +1* +b10111100 S +1U +1&" 1^" #942500000 -0) -0S -0$" +0* +0U +0&" 0^" #945000000 -1) -b10111101 R -1S -1$" +1* +b10111101 S +1U +1&" 1^" #947500000 -0) -0S -0$" +0* +0U +0&" 0^" #950000000 -1) -b10111110 R -1S -1$" +1* +b10111110 S +1U +1&" 1^" #952500000 -0) -0S -0$" +0* +0U +0&" 0^" #955000000 -1) -b10111111 R -1S -1$" +1* +b10111111 S +1U +1&" 1^" #957500000 -0) -0S -0$" +0* +0U +0&" 0^" #960000000 -1) -b11000000 R -1S -1$" +1* +b11000000 S +1U +1&" 1^" #962500000 -0) -0S -0$" +0* +0U +0&" 0^" #965000000 -1) -b11000001 R -1S -1$" +1* +b11000001 S +1U +1&" 1^" #967500000 -0) -0S -0$" +0* +0U +0&" 0^" #970000000 -1) -b11000010 R -1S -1$" +1* +b11000010 S +1U +1&" 1^" #972500000 -0) -0S -0$" +0* +0U +0&" 0^" #975000000 -1) -b11000011 R -1S -1$" +1* +b11000011 S +1U +1&" 1^" #977500000 -0) -0S -0$" +0* +0U +0&" 0^" #980000000 -1) -b11000100 R -1S -1$" +1* +b11000100 S +1U +1&" 1^" #982500000 -0) -0S -0$" +0* +0U +0&" 0^" #985000000 -1) -b11000101 R -1S -1$" +1* +b11000101 S +1U +1&" 1^" #987500000 -0) -0S -0$" +0* +0U +0&" 0^" #990000000 -1) -b11000110 R -1S -1$" +1* +b11000110 S +1U +1&" 1^" #992500000 -0) -0S -0$" +0* +0U +0&" 0^" #995000000 -1) -b11000111 R -1S -1$" +1* +b11000111 S +1U +1&" 1^" #997500000 -0) -0S -0$" +0* +0U +0&" 0^" #1000000000 -1) -b11001000 R -1S -1$" +1* +b11001000 S +1U +1&" 1^" diff --git a/ghdl/axi4-to-axis/waveform.gtkw b/ghdl/axi4-to-axis/waveform.gtkw index b75759c..0145bb7 100644 --- a/ghdl/axi4-to-axis/waveform.gtkw +++ b/ghdl/axi4-to-axis/waveform.gtkw @@ -1,21 +1,21 @@ [*] [*] GTKWave Analyzer v3.3.100 (w)1999-2019 BSI -[*] Fri Apr 21 12:57:05 2023 +[*] 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] "Fri Apr 21 12:53:49 2023" -[dumpfile_size] 21480 +[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] 1920 1057 -[pos] -1 -1 -*-25.000000 72400000 -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 +[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] 174 +[signals_width] 214 [sst_expanded] 1 [sst_vpaned_height] 314 -@22 +@24 [color] 5 tb_axis.clk_count[7:0] @28 @@ -25,9 +25,6 @@ tb_axis.clk tb_axis.rst_n tb_axis.axi_converter_inst.s_axi_awvalid tb_axis.axi_converter_inst.s_axi_awready -@22 -tb_axis.axi_converter_inst.s_axi_awaddr[19:0] -@28 tb_axis.axi_converter_inst.s_axi_awburst[1:0] @22 tb_axis.axi_converter_inst.s_axi_awlen[7:0] @@ -38,11 +35,13 @@ tb_axis.axi_converter_inst.s_axi_awid[2:0] tb_axis.axi_converter_inst.s_axi_wvalid [color] 2 tb_axis.axi_converter_inst.s_axi_wready -@22 +@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 @@ -53,10 +52,14 @@ 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 -@22 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/img/gtkwave_axi-to-axis.png b/img/gtkwave_axi-to-axis.png new file mode 100644 index 0000000000000000000000000000000000000000..6c620fe7a0a97294a951f5deeb1775d636d5d52a GIT binary patch literal 232941 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%0D#w)_ERnJ-RFn40Rb6ALO<4ZZBv3MODBG&~_PW#a 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 z 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 literal 0 HcmV?d00001 From 1c841cc0044ee810a826dff675c5949d016c4f48 Mon Sep 17 00:00:00 2001 From: Simon Burkhardt Date: Tue, 25 Apr 2023 09:35:39 +0200 Subject: [PATCH 6/7] remove AXIS data with paramter --- ghdl/axi4-to-axis/axi4_to_axis.vhd | 32 ++++++++++++++---------------- ghdl/axi4-to-axis/tb_axis.vhd | 19 +++++++----------- ghdl/axi4-to-axis/wave.vcd | 2 +- 3 files changed, 23 insertions(+), 30 deletions(-) diff --git a/ghdl/axi4-to-axis/axi4_to_axis.vhd b/ghdl/axi4-to-axis/axi4_to_axis.vhd index 55f5942..9b4e32e 100644 --- a/ghdl/axi4-to-axis/axi4_to_axis.vhd +++ b/ghdl/axi4-to-axis/axi4_to_axis.vhd @@ -42,10 +42,8 @@ entity axi4_to_axis is -- 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; - - -- Width of S_AXIS address bus. The slave accepts the read and write addresses of width C_M_AXIS_DATA_WIDTH. - C_M_AXIS_DATA_WIDTH : integer := 32 + C_S_AXI_BUSER_WIDTH : integer := 0 + ); port ( -- Users to add ports here @@ -187,9 +185,9 @@ entity axi4_to_axis is -- 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_M_AXIS_DATA_WIDTH-1 downto 0); + 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_M_AXIS_DATA_WIDTH/8)-1 downto 0); + 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. @@ -210,12 +208,12 @@ architecture arch_imp of axi4_to_axis is 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_M_AXIS_DATA_WIDTH+(C_M_AXIS_DATA_WIDTH/8)) - 1 downto 0); + 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_M_AXIS_DATA_WIDTH+(C_M_AXIS_DATA_WIDTH/8)) - 1 downto 0)); + 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); @@ -226,16 +224,16 @@ architecture arch_imp of axi4_to_axis is signal aresetn : std_logic; signal i_s_axis_tvalid : std_logic := '0'; - signal i_s_axis_tdata : std_logic_vector(C_M_AXIS_DATA_WIDTH-1 downto 0); - signal i_s_axis_data_strb : std_logic_vector(C_M_AXIS_DATA_WIDTH+(C_M_AXIS_DATA_WIDTH/8)-1 downto 0); - signal i_s_axis_tstrb : std_logic_vector((C_M_AXIS_DATA_WIDTH/8)-1 downto 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_M_AXIS_DATA_WIDTH-1 downto 0); - signal o_m_axis_data_strb : std_logic_vector(C_M_AXIS_DATA_WIDTH+(C_M_AXIS_DATA_WIDTH/8)-1 downto 0); - signal o_m_axis_tstrb : std_logic_vector((C_M_AXIS_DATA_WIDTH/8)-1 downto 0); + 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'; @@ -344,8 +342,8 @@ begin -- 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_M_AXIS_DATA_WIDTH+(C_M_AXIS_DATA_WIDTH/8)) - 1 downto (C_M_AXIS_DATA_WIDTH/8) ); - o_m_axis_tstrb <= o_m_axis_data_strb( (C_M_AXIS_DATA_WIDTH/8) - 1 downto 0 ); + 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 @@ -428,7 +426,7 @@ begin skidbuffer_inst : skidbuffer generic map ( - DATA_WIDTH => (C_M_AXIS_DATA_WIDTH+(C_M_AXIS_DATA_WIDTH/8)), + DATA_WIDTH => (C_S_AXI_DATA_WIDTH+(C_S_AXI_DATA_WIDTH/8)), OPT_DATA_REG => True ) port map ( diff --git a/ghdl/axi4-to-axis/tb_axis.vhd b/ghdl/axi4-to-axis/tb_axis.vhd index 9c14c6a..59b0278 100644 --- a/ghdl/axi4-to-axis/tb_axis.vhd +++ b/ghdl/axi4-to-axis/tb_axis.vhd @@ -55,10 +55,7 @@ entity tb_axis is -- 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; - - -- Width of S_AXIS address bus. The slave accepts the read and write addresses of width C_M_AXIS_DATA_WIDTH. - C_M_AXIS_DATA_WIDTH : integer := 8 + C_S_AXI_BUSER_WIDTH : integer := 0 ); end tb_axis; @@ -73,8 +70,7 @@ architecture bh of tb_axis is C_S_AXI_ARUSER_WIDTH : integer; C_S_AXI_WUSER_WIDTH : integer; C_S_AXI_RUSER_WIDTH : integer; - C_S_AXI_BUSER_WIDTH : integer; - C_M_AXIS_DATA_WIDTH : integer + C_S_AXI_BUSER_WIDTH : integer ); port ( AXIS_ACLK : in std_logic; @@ -126,8 +122,8 @@ architecture bh of tb_axis is S_AXI_RREADY : in std_logic; M_AXIS_TVALID : out std_logic; - M_AXIS_TDATA : out std_logic_vector(C_M_AXIS_DATA_WIDTH-1 downto 0); - M_AXIS_TSTRB : out std_logic_vector((C_M_AXIS_DATA_WIDTH/8)-1 downto 0); + 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 ); @@ -141,8 +137,8 @@ architecture bh of tb_axis is 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_M_AXIS_DATA_WIDTH-1 downto 0); - signal o_axis_tstrb : std_logic_vector((C_M_AXIS_DATA_WIDTH/8)-1 downto 0); + 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'; @@ -464,8 +460,7 @@ begin 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, - C_M_AXIS_DATA_WIDTH => C_M_AXIS_DATA_WIDTH + C_S_AXI_BUSER_WIDTH => C_S_AXI_BUSER_WIDTH ) port map ( AXIS_ACLK => clk, diff --git a/ghdl/axi4-to-axis/wave.vcd b/ghdl/axi4-to-axis/wave.vcd index 8bf473b..6cd995c 100644 --- a/ghdl/axi4-to-axis/wave.vcd +++ b/ghdl/axi4-to-axis/wave.vcd @@ -1,5 +1,5 @@ $date - Mon Apr 24 16:02:53 2023 + Tue Apr 25 09:35:10 2023 $end $version GHDL v0 From b3a2a89dc77ed8e222176519727f7259edaa9d6b Mon Sep 17 00:00:00 2001 From: Simon Burkhardt Date: Tue, 23 May 2023 15:33:23 +0200 Subject: [PATCH 7/7] add documentation --- README.md | 54 +++++++++++++++++++++++--------------- ghdl/axi4-to-axis/wave.vcd | 2 +- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 3021473..351369a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,30 @@ # AXI Stream compatible Skidbuffer in VHDL +--- -# Idea +## AXI4 to AXIS converter -## Passthrough Skid Buffer +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. + +### Features + +- 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`) + +![img/gtkwave_axi-to-axis.png](img/gtkwave_axi-to-axis.png) + +--- +## Skidbuffer Idea + +### Passthrough Skid Buffer Only the reply signal from downstream slave to upstream master (`tready`) is pipelined. @@ -10,27 +32,27 @@ All other signals from upstream master to downstream slave (`tvalid`, `tdata`, ` 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. -### Schematic +#### Schematic ![img/skidbuf_passthru.png](img/skidbuf_passthru.png) -### Waveform +#### Waveform ![img/skidbuf_passthru_wave.svg](img/skidbuf_passthru_wave.svg) ![img/gtkwave_passthru.png](img/gtkwave_passthru.png) -## Fully Pipelined Skid Buffer +### Fully Pipelined Skid Buffer 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. -### Schematic +#### Schematic ![img/skidbuf_fullreg.png](img/skidbuf_fullreg.png) -### Waveform +#### Waveform ![img/skidbuf_fullreg_wave.svg](img/skidbuf_fullreg_wave.svg) ![img/gtkwave_fullreg.png](img/gtkwave_fullreg.png) -# Simulation +## Simulation Assuming `ghdl` and `gtkwave` installed on Windows. @@ -40,19 +62,6 @@ Run in powershell: .\compile.bat ``` -## AXI4 Full to AXI-Stream converter - -Convert AXI4 write bursts to AXI-Slave protocol. - -- accepts AXI4 AW-channel handshake -- acknowledges successful transfer via `bresp` on B-channel after `axis_tlast` -- transfer AXI4 W-channel to AXI-S using skidbuffer -- supports `axis_tready` backpressure to `axi_awready` and `axi_wready` -- supports full throughput bandwidth with back-to-back burst transfer without wait cycles - -![img/gtkwave_axi-to-axis.png](img/gtkwave_axi-to-axis.png) - - # Acknowledgements https://zipcpu.com/blog/2019/05/22/skidbuffer.html @@ -64,4 +73,7 @@ This article did **NOT** help: it is confusing since the code does not match the https://www.itdev.co.uk/blog/pipelining-axi-buses-registered-ready-signals +# Tools + +Simulated using GHDL 3.7 / implemented and tested with Xilinx Vivado 2021.2 diff --git a/ghdl/axi4-to-axis/wave.vcd b/ghdl/axi4-to-axis/wave.vcd index 6cd995c..4cb5e68 100644 --- a/ghdl/axi4-to-axis/wave.vcd +++ b/ghdl/axi4-to-axis/wave.vcd @@ -1,5 +1,5 @@ $date - Tue Apr 25 09:35:10 2023 + Thu May 04 16:43:42 2023 $end $version GHDL v0