diff --git a/.gitignore b/.gitignore index 8f431b7..bdd7612 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ .locale/ -build/ \ No newline at end of file diff --git a/build/.gitignore b/build/.gitignore new file mode 100644 index 0000000..97e2ef4 --- /dev/null +++ b/build/.gitignore @@ -0,0 +1,2 @@ +working/ +reports/ \ No newline at end of file diff --git a/build/LICENSE.md b/build/LICENSE.md new file mode 100644 index 0000000..cf1ab25 --- /dev/null +++ b/build/LICENSE.md @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/build/Makefile b/build/Makefile new file mode 100644 index 0000000..d558860 --- /dev/null +++ b/build/Makefile @@ -0,0 +1,275 @@ +########################################################################### +## Xilinx ISE Makefile +## +## To the extent possible under law, the author(s) have dedicated all copyright +## and related and neighboring rights to this software to the public domain +## worldwide. This software is distributed without any warranty. +## +## Makefile github repository: https://github.com/PxaMMaxP/Xilinx-ISE-Makefile +########################################################################### + +########################################################################### +# Version +########################################################################### + +Makefile_Version := 1.1.5 +$(info ISE Makefile Version: $(Makefile_Version)) + +########################################################################### +# Include project configuration +########################################################################### + +include ../project.cfg + +########################################################################### +# Default values +########################################################################### + +ifndef XILINX + $(error XILINX must be defined) +endif + +ifndef PROJECT + $(error PROJECT must be defined) +endif + +ifndef TARGET_PART + $(error TARGET_PART must be defined) +endif + +TOPLEVEL ?= $(PROJECT) +CONSTRAINTS ?= $(PROJECT).ucf +BUILD_DIR ?= working +REPORT_DIR ?= reports +BITFILE ?= $(BUILD_DIR)/$(PROJECT).bit + +COMMON_OPTS ?= -intstyle xflow +XST_OPTS ?= +NGDBUILD_OPTS ?= +MAP_OPTS ?= -detail +PAR_OPTS ?= +BITGEN_OPTS ?= +TRACE_OPTS ?= -v 3 -n 3 +FUSE_OPTS ?= -incremental + +ISIM_OPTS ?= -gui +ISIM_CMD ?= + +PROGRAMMER ?= none +PROGRAMMER_PRE ?= + +IMPACT_OPTS ?= -batch impact.cmd + +DJTG_EXE ?= djtgcfg +DJTG_DEVICE ?= DJTG_DEVICE-NOT-SET +DJTG_INDEX ?= 0 +DJTG_FLASH_INDEX ?= 1 + +XC3SPROG_EXE ?= xc3sprog +XC3SPROG_CABLE ?= none +XC3SPROG_OPTS ?= + + +########################################################################### +# Internal variables, platform-specific definitions, and macros +########################################################################### + +ifeq ($(OS),Windows_NT) + XILINX := $(shell cygpath -m $(XILINX)) + CYG_XILINX := $(shell cygpath $(XILINX)) + EXE := .exe + XILINX_PLATFORM ?= nt64 + PATH := $(PATH):$(CYG_XILINX)/bin/$(XILINX_PLATFORM) +else + EXE := + XILINX_PLATFORM ?= lin64 + PATH := $(PATH):$(XILINX)/bin/$(XILINX_PLATFORM) +endif + +TEST_NAMES = $(foreach file,$(VTEST) $(VHDTEST),$(basename $(file))) +TEST_EXES = $(foreach test,$(TEST_NAMES),$(BUILD_DIR)/isim_$(test)$(EXE)) + +RUN = @echo "\n\e[1;33m============ $(1) ============\e[m\n"; \ + cd $(BUILD_DIR) && $(XILINX)/bin/$(XILINX_PLATFORM)/$(1) + +# isim executables don't work without this +export XILINX + +# Initialize the libs and paths variables for VHDL and Verilog sources +VHD_PATHS ?= +VHD_LIBS ?= +V_PATHS ?= +V_LIBS ?= + +# Define a function to process source files +define process_sources +$(foreach src,$(1),\ + $(eval lib_and_path=$(subst :, ,$(src))) \ + $(eval libname=$(word 1,$(lib_and_path))) \ + $(eval filepath=$(word 2,$(lib_and_path))) \ + $(if $(filepath),,$(eval filepath=$(libname)) $(eval libname=work)) \ + $(eval $(2) += $(libname)) \ + $(eval $(3) += ../$(filepath)) \ +) +endef + +# Run the function for VHDL sources +$(eval $(call process_sources,$(VHDSOURCE),VHD_LIBS,VHD_PATHS)) +# Run the function for Verilog sources +$(eval $(call process_sources,$(VSOURCE),V_LIBS,V_PATHS)) + +## Tests + +# Initialize the libs and paths variables for VHDL and Verilog testbenches +VHD_TEST_PATHS ?= +VHD_TEST_LIBS ?= +V_TEST_PATHS ?= +V_TEST_LIBS ?= + +# Run the function for VHDL tests +$(eval $(call process_sources,$(VHDTEST),VHD_TEST_LIBS,VHD_TEST_PATHS)) +# Run the function for Verilog tests +$(eval $(call process_sources,$(VTEST),V_TEST_LIBS,V_TEST_PATHS)) + +# Get the test names.. +TEST_PATHS = $(foreach file,$(V_TEST_PATHS) $(VHD_TEST_PATHS),$(basename $(file))) +TEST_NAMES = $(foreach path,$(TEST_PATHS),$(notdir $(path))) +TEST_EXES = $(foreach test,$(TEST_NAMES),$(BUILD_DIR)/isim_$(test)$(EXE)) + +########################################################################### +# Default build +########################################################################### + +default: $(BITFILE) + +clean: + rm -rf $(BUILD_DIR) + rm -rf $(REPORT_DIR) + +$(BUILD_DIR)/$(PROJECT).prj: ../project.cfg + @echo "Updating $@" + @mkdir -p $(BUILD_DIR) + @mkdir -p $(REPORT_DIR) + @rm -f $@ + @$(foreach idx,$(shell seq 1 $(words $(V_PATHS))),echo "verilog $(word $(idx),$(V_LIBS)) \"../$(word $(idx),$(V_PATHS))\"" >> $@;) + @$(foreach idx,$(shell seq 1 $(words $(VHD_PATHS))),echo "vhdl $(word $(idx),$(VHD_LIBS)) \"../$(word $(idx),$(VHD_PATHS))\"" >> $@;) + + +$(BUILD_DIR)/$(PROJECT)_sim.prj: $(BUILD_DIR)/$(PROJECT).prj + @cp $(BUILD_DIR)/$(PROJECT).prj $@ + @$(foreach idx,$(shell seq 1 $(words $(V_TEST_PATHS))),echo "verilog $(word $(idx),$(V_TEST_LIBS)) \"../$(word $(idx),$(V_TEST_PATHS))\"" >> $@;) + @$(foreach idx,$(shell seq 1 $(words $(VHD_TEST_PATHS))),echo "vhdl $(word $(idx),$(VHD_TEST_LIBS)) \"../$(word $(idx),$(VHD_TEST_PATHS))\"" >> $@;) + @echo "verilog work $(XILINX)/verilog/src/glbl.v" >> $@ + +$(BUILD_DIR)/$(PROJECT).scr: ../project.cfg + @echo "Updating $@" + @mkdir -p $(BUILD_DIR) + @rm -f $@ + @echo "run" \ + "-ifn $(PROJECT).prj" \ + "-ofn $(PROJECT).ngc" \ + "-ifmt mixed" \ + "$(XST_OPTS)" \ + "-top $(TOPLEVEL)" \ + "-ofmt NGC" \ + "-p $(TARGET_PART)" \ + > $(BUILD_DIR)/$(PROJECT).scr + +$(BITFILE): ../project.cfg $(V_PATHS) $(VHD_PATHS) ../$(CONSTRAINTS) $(BUILD_DIR)/$(PROJECT).prj $(BUILD_DIR)/$(PROJECT).scr + @mkdir -p $(BUILD_DIR) + @mkdir -p $(REPORT_DIR) + $(call RUN,xst) $(COMMON_OPTS) \ + -ifn $(PROJECT).scr + @cp ./$(BUILD_DIR)/$(PROJECT).srp $(REPORT_DIR)/$(PROJECT).SynthesisReport + $(call RUN,ngdbuild) $(COMMON_OPTS) $(NGDBUILD_OPTS) \ + -p $(TARGET_PART) -uc ../../$(CONSTRAINTS) \ + $(PROJECT).ngc $(PROJECT).ngd + $(call RUN,map) $(COMMON_OPTS) $(MAP_OPTS) \ + -p $(TARGET_PART) \ + -w $(PROJECT).ngd -o $(PROJECT).map.ncd $(PROJECT).pcf + @cp ./$(BUILD_DIR)/$(PROJECT).map.mrp $(REPORT_DIR)/$(PROJECT).MapReport + $(call RUN,par) $(COMMON_OPTS) $(PAR_OPTS) \ + -w $(PROJECT).map.ncd $(PROJECT).ncd $(PROJECT).pcf + @cp ./$(BUILD_DIR)/$(PROJECT).par $(REPORT_DIR)/$(PROJECT).PlaceRouteReport + $(call RUN,bitgen) $(COMMON_OPTS) $(BITGEN_OPTS) \ + -w $(PROJECT).ncd $(PROJECT).bit + @echo "\e[1;32m============ OK ============\e[m\n\n" + @echo "\e[1;33m============ Reports.. ===========\e[m\n" + @echo "\e[1;97m==== Synthesis Summary Report ====\e[m" + @echo "\e[1;35m ./$(REPORT_DIR)/$(PROJECT).SynthesisReport\e[m\n" + @echo "\e[1;97m======= Map Summary Report =======\e[m" + @echo "\e[1;35m ./$(REPORT_DIR)/$(PROJECT).MapReport\e[m\n" + @echo "\e[1;97m======= PAR Summary Report =======\e[m" + @echo "\e[1;35m ./$(REPORT_DIR)/$(PROJECT).PlaceRouteReport\e[m\n" + @echo "\e[1;97m===== Pinout Summary Report ======\e[m" + @cp ./$(BUILD_DIR)/$(PROJECT)_pad.txt $(REPORT_DIR)/$(PROJECT).PinoutReport + @echo "\e[1;35m ./$(REPORT_DIR)/$(PROJECT).PinoutReport\e[m\n" + +copy: $(BITFILE) + @cp $(BITFILE) $(COPY_TARGET_DIR)/$(PROJECT).bit + @echo "\n\e[1;32m= Copy bitfile successful =\e[m\n" + +########################################################################### +# Testing (work in progress) +########################################################################### + +trace: ../project.cfg $(BITFILE) + $(call RUN,trce) $(COMMON_OPTS) $(TRACE_OPTS) \ + $(PROJECT).ncd $(PROJECT).pcf + @echo "\n\e[1;33m============ Reports.. ===========\e[m\n" + @echo "\e[1;97m===== Timing Summary Report ======\e[m" + @cp ./$(BUILD_DIR)/$(PROJECT).twr $(REPORT_DIR)/$(PROJECT).TimingReport + @echo "\e[1;35m ./$(REPORT_DIR)/$(PROJECT).TimingReport\e[m\n" + +test: buildtest runtest + +runtest: ${TEST_NAMES} + +${TEST_NAMES}: + @grep --no-filename --no-messages 'ISIM:' $@.{v,vhd} | cut -d: -f2 > $(BUILD_DIR)/isim_$@.cmd + @echo "$(ISIM_CMD)" >> $(BUILD_DIR)/isim_$@.cmd + cd $(BUILD_DIR) ; ./isim_$@$(EXE) $(ISIM_OPTS) -tclbatch isim_$@.cmd ; + +buildtest: ${TEST_EXES} + +$(BUILD_DIR)/isim_%$(EXE): $(BUILD_DIR)/$(PROJECT)_sim.prj $(V_PATHS) $(VHD_PATHS) ${V_TEST_PATHS} $(VHD_TEST_PATHS) + $(call RUN,fuse) $(COMMON_OPTS) $(FUSE_OPTS) \ + -prj $(PROJECT)_sim.prj \ + -o isim_$*$(EXE) \ + work.$* work.glbl + + +########################################################################### +# Programming +########################################################################### + +ifeq ($(PROGRAMMER), impact) +prog: $(BITFILE) + $(PROGRAMMER_PRE) $(XILINX)/bin/$(XILINX_PLATFORM)/impact $(IMPACT_OPTS) +endif + +ifeq ($(PROGRAMMER), digilent) +prog: $(BITFILE) + $(PROGRAMMER_PRE) $(DJTG_EXE) prog -d $(DJTG_DEVICE) -i $(DJTG_INDEX) -f $(BITFILE) +endif + +ifeq ($(PROGRAMMER), xc3sprog) +prog: $(BITFILE) + $(PROGRAMMER_PRE) $(XC3SPROG_EXE) -c $(XC3SPROG_CABLE) $(XC3SPROG_OPTS) $(BITFILE) +endif + +ifeq ($(PROGRAMMER), none) +prog: + $(error PROGRAMMER must be set to use 'make prog') +endif + +########################################################################### +# Flash +########################################################################### + +ifeq ($(PROGRAMMER), digilent) +flash: $(BITFILE) + $(PROGRAMMER_PRE) $(DJTG_EXE) prog -d $(DJTG_DEVICE) -i $(DJTG_FLASH_INDEX) -f $(BITFILE) +endif + +########################################################################### diff --git a/build/README.md b/build/README.md new file mode 100644 index 0000000..1a756bd --- /dev/null +++ b/build/README.md @@ -0,0 +1,225 @@ +# Xilinx ISE Makefile + +Tired of clicking around in Xilinx ISE? Run your builds from the command line! + +## Forked from.. + +The original project is located at [Xilinx-ISE-Makefile](https://github.com/duskwuff/Xilinx-ISE-Makefile) and was created by [duskwuff](github.com/duskwuff/). + +Many thanks for the good work! + +## Requirements + +- Xilinx ISE, ideally 14.7 (the final version) + + Works great on Linux. Windows Subsystem for Linux is tested and works well. + +- GNU (or compatible?) Make + + Install this through Cygwin on Windows. + +## Creating a project + +To start building a project, you will need to create a file `project.cfg` in +the top level of your project. This file is a text file sourced by Make, so +it consists of `KEY = value` pairs. It must define at least the following keys: + +- `PROJECT` + + The name of the project, used as a name for certain intermediate files, and + as the default name for the top-level module and constraints file. + +- `TARGET_PART` + + The full part-speed-package identifier for the Xilinx part to be targeted, + e.g. `xc6slx9-2-tqg144`. + +- `XILINX` + + The path to the appropriate binaries directory of the target Xilinx ISE + install, e.g. + `/cygdrive/c/Xilinx/14.7/ISE_DS/ISE` + or + `/opt/Xilinx/14.7/ISE_DS/ISE` + for typical installs. + +- `VSOURCE` and/or `VHDSOURCE` + + The space-separated names of all Verilog and/or VHDL source files to be + used in the project. + + You can define these on multiple lines using `+=`, e.g. + + VSOURCE += foo.v + VSOURCE += bar.v + + You can also add a library name to the source file, e.g. + + VSOURCE += my_lib:foo.v + VSOURCE += my_lib:bar.v + + The default library name is `work`. + +A simple `project.cfg` may thus resemble: + + PROJECT = example + TARGET_PART = xc6slx9-2-cpg196 + + XILINX = /cygdrive/c/Xilinx/14.7/ISE_DS/ISE/bin/nt64 + + VSOURCE = example.v + +A number of other keys can be set in the project configuration, including: + +- `XILINX_PLATFORM` + + The Xilinx name for the platform to build for, e.g. `nt64` or `lin`. + `nt64` is used by default for Windows systems, and `lin64` for Linux + systems, so you only need to set this if you explicitly need to use the + 32-bit version of the tools for some reason. + +- `TOPLEVEL` + + The name of the top-level module to be used in the project. + (Defaults to `$PROJECT`.) + +- `CONSTRAINTS` + + The name of the constraints file (`.ucf`) to be used for the project. + (Defaults to `$PROJECT.ucf`.) + +- `COMMON_OPTS` + + Extra command-line options to be passed to all ISE executables. Defaults to + `-intstyle xflow`. + +- `XST_OPTS`, `NGDBUILD_OPTS`, `MAP_OPTS`, `PAR_OPTS`, `BITGEN_OPTS`, + `TRACE_OPTS`, `FUSE_OPTS` + + Extra command-line options to be passed to the corresponding ISE tools. + + Defaults is: + + ``` + XST_OPTS ?= + NGDBUILD_OPTS ?= + MAP_OPTS ?= -detail + PAR_OPTS ?= + BITGEN_OPTS ?= + TRACE_OPTS ?= -v 3 -n 3 + FUSE_OPTS ?= -incremental + ``` + + Note that `XST_OPTS` will not appear on the command line during + compilation, as the XST options are embedded in a script file. + + `MAP_OPTS` and `PAR_OPTS` can be set to `-mt 2` to use multithreading, + which may speed up compilation of large designs. + + `BITGEN_OPTS` can be set to `-g Compress` to apply bitstream compression. + +- `PROGRAMMER` + + The name of the programmer to be used for `make prog`. Currently supported + values are: + + - `impact` + + Uses Xilinx iMPACT for programming, using a batch file named + `impact.cmd` by default. The iMPACT command line may be overridden by + setting `IMPACT_OPTS`. + + A typical batch file may resemble: + + setMode -bscan + setCable -p auto + addDevice -p 1 -file build/projectname.bit + program -p 1 + quit + + - `digilent` + + Uses the Digilent JTAG utility for programming, which must be installed + separately. The name of the board must be set as `DJTG_DEVICE`; the + path to the djtgcfg executable can be set as `DJTG_EXE`, and the index + of the device can be set as `DJTG_INDEX`. You can set the flash index + with `DJTG_FLASH_INDEX`. + + - `xc3sprog` + + Uses the xc3sprog utility for programming, which must also be installed + separately. The cable name must be set as `XC3SPROG_CABLE`; additional + options can be set as `XC3SPROG_OPTS`. + +- `PROGRAMMER_PRE` + + A command to be run before programming. This can be used to use `sudo` or + `yes` to confirm programming. + +## Targets + +The Xilinx ISE Makefile implements the following targets: + +- `make default` (or just `make`) + + Builds the bitstream. + +- `make clean` + + Removes the build directory. + +- `make prog` + + Writes the bitstream to a target device. Requires some additional + configuration; see below for details. + +- `make flash` + + Writes the bitstream to a flash device. + **This is currently only for digilent implemented.** + +## Console output + +After a successful build, you will find the paths to the generated **reports** on the console. E.g.: + +``` +============ Reports.. =========== + +==== Synthesis Summary Report ==== + ./build/Example.srp + +======= Map Summary Report ======= + ./build/Example.map.mrp + +======= PAR Summary Report ======= + ./build/Example.par + +===== Pinout Summary Report ====== + ./build/Example_pad.txt + +``` + +## Unimplemented features + +The following features are not currently implemented. (Pull requests are +encouraged!) + +- Generation of SPI or other unusual programming files + +- CPLD synthesis + +- Synthesis tools other than XST + +- Display and/or handling of warnings and errors from `build/_xmsgs` + +- Running unit tests + +- Anything else (open an issue?) + +## License + +To the extent possible under law, the author(s) have dedicated all copyright +and related and neighboring rights to this software to the public domain +worldwide. This software is distributed without any warranty. + +See LICENSE.md for details. diff --git a/build/project.cfg.sample b/build/project.cfg.sample new file mode 100644 index 0000000..30df022 --- /dev/null +++ b/build/project.cfg.sample @@ -0,0 +1,110 @@ +## Main settings.. ## + +# Project name +# @remark The name of the project is used as default name for the top module and the ucf file +PROJECT = + +# Target device +# @example xc3s1200e-4-fg320 | xc5vlx50t-1-ff1136 +TARGET_PART = + +# Path to the Xilinx ISE installation +XILINX = /opt/Xilinx/14.7/ISE_DS/ISE + +# Optional the name of the top module (default is the project name) +# TOPLEVEL = + +# Optional the path/name of the ucf file (default is the project name) +# CONSTRAINTS = + +# Optional a target to copy the bit file to (make copy) +# COPY_TARGET_DIR = + +## ## ## ## ## ## ## ## +# --------------------- + +## Source files settings.. ## +# The source files to be compiled +# @example `VSOURCE += src/main.v` (add a single Verilog file per line) +# @example `VHDSOURCE += src/main.vhd` (add a single VHDL file per line) + + +## Test files settings.. ## +# The testbench files to be compiled +# @example `VTEST += tests/main_tb.v` (add a single Verilog testbench file per line) +# @example `VHDTEST += tests/main_tb.vhd` (add a single VHDL testbench file per line) + + +## ## ## ## ## ## ## ## +# --------------------- + +## ISE executable settings.. ## + +# General command line options to be passed to all ISE executables (default is `-intstyle xflow`) +# COMMON_OPTS = + +# Options for the XST synthesizer +# @example -register_balancing (yes|no) +# @example -opt_mode (speed|area) +# @example -opt_level (1|2) +XST_OPTS = + +# Options for the NGDBuild tool +# NGDBUILD_OPTS = + +# Options for the MAP tool +# @example -mt 2 (multi-threading with 2 threads) +# @example -cm speed (speed optimization) +# @example -ol high +# @example -detail +# @example -timing +MAP_OPTS = + +# Options for the PAR tool +# @example -mt 2 (multi-threading with 2 threads) +# @example -ol high +PAR_OPTS = + +# Options for the BitGen tool +# @example -g Compress (compress bitstream) +# @example -g StartupClk:Cclk (specify the startup clock to onboard clock) +# @example -g StartupClk:JtagClk (specify the startup clock to JTAG clock) +BITGEN_OPTS = -g StartupClk:JtagClk + +# Options for the Trace tool +# TRACE_OPTS = + +# Options for the Fuse tool +# FUSE_OPTS = + +# Options for the ISim simulator +# @example -gui (start the simulator in GUI mode) +# ISIM_OPTS = + +# Options for the ISim batch file +# @example vcd dumpfile $@.vcd \n vcd dumpvars -m /UUT \n run all \n vcd dumpflush \n quit +# ISIM_CMD = + +## ## ## ## ## ## ## ## +# --------------------- + +## Programmer settings.. ## + +# The programmer to use +# @example impact | digilent | xc3sprog +# @remark impact is the default Xilinx programmer and you must create a impact.cmd file in the root directory.. +PROGRAMMER = + +## Digilent JTAG cable settings + +# @remark Use the `djtgcfg enum` command to list all available devices +# DJTG_DEVICE = DOnbUsb + +# The index of the JTAG device for the `prog` target +# DJTG_INDEX = 0 + +# The index of the flash device for the `flash` target +# DJTG_FLASH_INDEX = 1 + +## ## ## ## ## ## ## ## +# --------------------- \ No newline at end of file diff --git a/project.cfg b/project.cfg index 5fb370a..0bbcfce 100644 --- a/project.cfg +++ b/project.cfg @@ -31,14 +31,14 @@ VHDSOURCE += ../Asynchronous-FIFO-AXI-Handshake/libs/Pipeline-AXI-Handshake/src/ VHDSOURCE += ../Asynchronous-FIFO-AXI-Handshake/libs/Pipeline-AXI-Handshake/src/PipelineController.vhd VHDSOURCE += ../Asynchronous-FIFO-AXI-Handshake/libs/Pipeline-AXI-Handshake/src/PipelineStage.vhd VHDSOURCE += ../Asynchronous-FIFO-AXI-Handshake/libs/Pipeline-AXI-Handshake/src/PipelineFilter.vhd -VHDSOURCE += libs/PriorityEncoders.vhd -VHDSOURCE += libs/AXI-HS-Scheduler/build/AXI_Handshaking_Scheduler_2.vhdl -VHDSOURCE += libs/AXI-HS-Scheduler/build/AXI_Handshaking_Scheduler_4.vhdl -VHDSOURCE += libs/AXI-HS-Scheduler/build/AXI_Handshaking_Scheduler_8.vhdl -VHDSOURCE += libs/AXI-HS-Scheduler/build/AXI_Handshaking_Scheduler_16.vhdl -VHDSOURCE += libs/AXI-HS-Scheduler/build/AXI_Handshaking_Scheduler_32.vhdl -VHDSOURCE += libs/AXI-HS-Scheduler/build/AXI_Handshaking_Scheduler_64.vhdl -VHDSOURCE += libs/AXI-HS-MUX/AXI_HS_MUX.vhd +# VHDSOURCE += libs/PriorityEncoders.vhd +# VHDSOURCE += libs/AXI-HS-Scheduler/build/AXI_Handshaking_Scheduler_2.vhdl +# VHDSOURCE += libs/AXI-HS-Scheduler/build/AXI_Handshaking_Scheduler_4.vhdl +# VHDSOURCE += libs/AXI-HS-Scheduler/build/AXI_Handshaking_Scheduler_8.vhdl +# VHDSOURCE += libs/AXI-HS-Scheduler/build/AXI_Handshaking_Scheduler_16.vhdl +# VHDSOURCE += libs/AXI-HS-Scheduler/build/AXI_Handshaking_Scheduler_32.vhdl +# VHDSOURCE += libs/AXI-HS-Scheduler/build/AXI_Handshaking_Scheduler_64.vhdl +# VHDSOURCE += libs/AXI-HS-MUX/AXI_HS_MUX.vhd VHDSOURCE += libs/OPCodes.vhd VHDSOURCE += src/VerticalSpritePipeline.vhd diff --git a/src/HorizontalSpritePipeline.vhd b/src/HorizontalSpritePipeline.vhd index c836c89..bc7f29b 100644 --- a/src/HorizontalSpritePipeline.vhd +++ b/src/HorizontalSpritePipeline.vhd @@ -10,7 +10,7 @@ --@ address and color data. --@ --@ The operation is fully pipelined and includes the following steps: ---@ - Latching of sprite index, offset, and X positions +--@ - Register of sprite index, offset, and X positions --@ - Calculation of the horizontal offset between request and sprite position --@ - Visibility check against the maximum sprite width --@ - ROM address generation for the sprite pixel @@ -31,66 +31,64 @@ use ieee.math_real.all; entity HorizontalSpritePipeline is generic ( --@ Width of the sprite index (Base address) register - G_Index_Width : integer := 5; + G_Index_Width : integer := 5; --@ Width of the sprite offset (Line address) register - G_Offset_Width : integer := 8; + G_Offset_Width : integer := 8; --@ Width of the X position (Row) register - G_X_Width : integer := 10; - --@ Width of the pixel data from rom - G_Rom_Width : integer := 8; + G_X_Width : integer := 10; --@ Width of the pixel data output - G_Pixel_Width : integer := 8; + G_Pixel_Width : integer := 8; --@ Horizontal width of a sprite in pixels - G_SpriteMaxWidth : integer := 16 + G_Sprite_MaxWidth : integer := 16 ); port ( --@ Clock; (**Rising edge** triggered) - I_CLK : in std_logic; + I_CLK : in std_logic; --@ Clock Enable; (**Synchronous**, **Active high**) - I_CE : in std_logic; + I_CE : in std_logic; --@ Reset; (**Synchronous**, **Active high**) - I_RST : in std_logic; + I_RST : in std_logic; --@ @virtualbus Operation @dir In Operation input bus --@ AXI like valid; (**Synchronous**, **Active high**) - I_OP_Valid : in std_logic; + I_HSpritePipeline_OP_Valid : in std_logic; --@ AXI like ready; (**Synchronous**, **Active high**) - O_OP_Ready : out std_logic; + O_HSpritePipeline_OP_Ready : out std_logic; --@ Index address - I_OP_Index : in std_logic_vector(G_Index_Width - 1 downto 0); + I_HSpritePipeline_OP_Index : in std_logic_vector(G_Index_Width - 1 downto 0); --@ Offset address - I_OP_Offset : in std_logic_vector(G_Offset_Width - 1 downto 0); + I_HSpritePipeline_OP_Offset : in std_logic_vector(G_Offset_Width - 1 downto 0); --@ X position of the request - I_OP_X_Request : in std_logic_vector(G_X_Width - 1 downto 0); + I_HSpritePipeline_OP_X_Request : in std_logic_vector(G_X_Width - 1 downto 0); --@ X position of the sprite - I_OP_X_Sprite : in std_logic_vector(G_X_Width - 1 downto 0); + I_HSpritePipeline_OP_X_Sprite : in std_logic_vector(G_X_Width - 1 downto 0); --@ @end - --@ @virtualbus Rom-Address @dir Out Request rom data bus + --@ @virtualbus Rom-Request @dir Out Request rom data bus --@ AXI like valid; (**Synchronous**, **Active high**) - O_Rom_Valid : out std_logic; + O_Rom_Valid : out std_logic; --@ AXI like ready; (**Synchronous**, **Active high**) - I_Rom_Ready : in std_logic; + I_Rom_Ready : in std_logic; --@ Rom address - O_Rom_Address : out std_logic_vector(G_Index_Width + G_Offset_Width - 1 downto 0); + O_Rom_Address : out std_logic_vector(G_Index_Width + G_Offset_Width - 1 downto 0); --@ @end --@ @virtualbus Rom-Data @dir In Rom data bus --@ AXI like valid; (**Synchronous**, **Active high**) - I_Rom_Valid : in std_logic; + I_Rom_Valid : in std_logic; --@ AXI like ready; (**Synchronous**, **Active high**) - O_Rom_Ready : out std_logic; + O_Rom_Ready : out std_logic; --@ Rom data - I_Rom_Data : in std_logic_vector(G_Rom_Width - 1 downto 0); + I_Rom_Data : in std_logic_vector(G_Pixel_Width - 1 downto 0); --@ @end - --@ @virtualbus Pixel-Data @dir Out Pixel data output bus + --@ @virtualbus Pixel-Data @dir Out Pixel data bus --@ AXI like valid; (**Synchronous**, **Active high**) - O_Pixel_Valid : out std_logic; + O_Pixel_Valid : out std_logic; --@ AXI like ready; (**Synchronous**, **Active high**) - I_Pixel_Ready : in std_logic; + I_Pixel_Ready : in std_logic; --@ Pixel data - O_Pixel_Data : out std_logic_vector(G_Pixel_Width - 1 downto 0) + O_Pixel_Data : out std_logic_vector(G_Pixel_Width - 1 downto 0) --@ @end ); end entity HorizontalSpritePipeline; @@ -142,8 +140,8 @@ begin I_CLK => I_CLK, I_CE => I_CE, O_Enable => O_HSpritePipelineCtrl_Enable, - I_Valid => I_OP_Valid, - O_Ready => O_OP_Ready, + I_Valid => I_HSpritePipeline_OP_Valid, + O_Ready => O_HSpritePipeline_OP_Ready, O_Valid => O_HSpritePipeline_Valid, I_Ready => I_HSpritePipeline_Ready ); @@ -157,7 +155,7 @@ begin port map( I_CLK => I_CLK, I_Enable => O_HSpritePipelineCtrl_Enable, - I_Data => I_OP_Index, + I_Data => I_HSpritePipeline_OP_Index, O_Data => R_Index ); @@ -170,7 +168,7 @@ begin port map( I_CLK => I_CLK, I_Enable => O_HSpritePipelineCtrl_Enable, - I_Data => I_OP_Offset, + I_Data => I_HSpritePipeline_OP_Offset, O_Data => R_Offset ); @@ -183,7 +181,7 @@ begin port map( I_CLK => I_CLK, I_Enable => O_HSpritePipelineCtrl_Enable, - I_Data => I_OP_X_Request, + I_Data => I_HSpritePipeline_OP_X_Request, O_Data => R_X_Request ); @@ -196,7 +194,7 @@ begin port map( I_CLK => I_CLK, I_Enable => O_HSpritePipelineCtrl_Enable, - I_Data => I_OP_X_Sprite, + I_Data => I_HSpritePipeline_OP_X_Sprite, O_Data => R_X_Sprite ); @@ -221,7 +219,7 @@ begin unsigned(R_Offset) + unsigned(R_Sprite_X_Offset(G_Offset_Width - 1 downto 0)) ); - C_X_Visible <= '1' when unsigned(R_Sprite_X_Offset) < G_SpriteMaxWidth else + C_X_Visible <= '1' when unsigned(R_Sprite_X_Offset) < G_Sprite_MaxWidth else '0'; INST_HSpritePipeline_Address : entity work.PipelineRegister diff --git a/src/OPDecoder.vhd b/src/OPDecoder.vhd index 4f9366f..021be94 100644 --- a/src/OPDecoder.vhd +++ b/src/OPDecoder.vhd @@ -25,66 +25,66 @@ entity OPDecoder is --@ Synchronous reset signal (**Active high**) I_RST : in std_logic; - --@ @virtualbus Operation-Write @dir in Operation Write Interface - --@ Indicates if the `OPCode` and `OPData` are valid. (**Active high**) - I_OP_Valid : in std_logic := '0'; - --@ Indicates if the decoder is ready to accept data. (**Active high**) - O_OP_Ready : out std_logic := '0'; + --@ @virtualbus Decoder-OP @dir in Operation Write Interface + --@ AXI like valid; (**Synchronous**, **Active high**) + I_OPDecoder_Valid : in std_logic := '0'; + --@ AXI like ready; (**Synchronous**, **Active high**) + O_OPDecoder_Ready : out std_logic := '0'; --@ Operation code for the sprite channel - I_OP_Code : in std_logic_vector(3 downto 0) := (others => '0'); - --@ Data to be used with the operation code. - I_OP_Data : in std_logic_vector(G_OPCodeData_Width - 1 downto 0) := (others => '0'); + I_OPDecoder_Code : in std_logic_vector(3 downto 0) := (others => '0'); + --@ Operation data for the sprite channel + I_OPDecoder_Data : in std_logic_vector(G_OPCodeData_Width - 1 downto 0) := (others => '0'); --@ @end --@ @virtualbus Register-Write @dir out Bus to write to the register file --@ Write enable for the sprite index register; (**Active high**) - O_Register_Index_WE : out std_logic := '0'; + O_RFile_Wr_Index_WE : out std_logic := '0'; --@ Data to write to the sprite index (Base address) register. - O_Register_Index : out std_logic_vector(G_Index_Width - 1 downto 0) := (others => '0'); + O_RFile_Wr_Index : out std_logic_vector(G_Index_Width - 1 downto 0) := (others => '0'); --@ Write enable for the sprite offset (line) register; (**Active high**) - O_Register_Offset_WE : out std_logic := '0'; + O_RFile_Wr_Offset_WE : out std_logic := '0'; --@ Data to write to the sprite offset (Line address) register. - O_Register_Offset : out std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0'); + O_RFile_Wr_Offset : out std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0'); --@ Write enable for the X position register. (**Active high**) - O_Register_X_We : out std_logic := '0'; + O_RFile_Wr_X_We : out std_logic := '0'; --@ Data to write to the X position register (Row) of the sprite. - O_Register_X : out std_logic_vector(G_X_Width - 1 downto 0) := (others => '0'); + O_RFile_Wr_X : out std_logic_vector(G_X_Width - 1 downto 0) := (others => '0'); --@ Write enable for the Y position register. (**Active high**) - O_Register_Y_WE : out std_logic := '0'; + O_RFile_Wr_Y_WE : out std_logic := '0'; --@ Data to write to the Y position register (Line) of the sprite. - O_Register_Y : out std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0'); + O_RFile_Wr_Y : out std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0'); --@ Write enable for the `IsVisible` flag. (**Active high**) - O_IsVisible_WE : out std_logic := '0'; + O_RFile_Wr_IsVisible_WE : out std_logic := '0'; --@ Flag to write to the `IsVisible` flag. - O_IsVisible : out std_logic := '0'; + O_RFile_Wr_IsVisible : out std_logic := '0'; --@ @end --@ @virtualbus Register-Read @dir In Parallel read interface to the register file --@ Indicates if the sprite is in the line visible. - I_IsVisible : in std_logic := '0'; + I_RFile_IsVisible : in std_logic := '0'; --@ @end - --@ @virtualbus YHitCheck-Input-Interface @dir in YHitCheck Input Interface - --@ Indicates if the pipeline is ready to accept data. **Active high** - I_YHitCheck_Ready : in std_logic := '0'; - --@ Indicates if the pipeline is valid. **Active high** - O_YHitCheck_Valid : out std_logic := '0'; - --@ The line to check if the sprite is in the line visible. - O_YHitCheck_YToCheck : out std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0'); + --@ @virtualbus VSpritePipeline-OP @dir Out Vertical sprite pipeline operation interface + --@ AXI like ready; (**Synchronous**, **Active high**) + I_VSpritePipeline_Ready : in std_logic := '0'; + --@ AXI like valid; (**Synchronous**, **Active high**) + O_VSpritePipeline_Valid : out std_logic := '0'; + --@ The requested Y position (line). + O_VSpritePipeline_YToCheck : out std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0'); --@ @end - --@ @virtualbus YHitCheck-Output-Interface @dir out YHitCheck Output Interface - --@ Indicates if the pipeline is ready to deliver data. **Active high** - O_YHitCheck_Ready : out std_logic := '0'; - --@ Indicates if `O_IsVisible` is valid. **Active high** - I_YHitCheck_Valid : in std_logic := '0'; + --@ @virtualbus VSpritePipeline-Result @dir In Vertical sprite pipeline result interface + --@ AXI like ready; (**Synchronous**, **Active high**) + O_VSpritePipeline_Ready : out std_logic := '0'; + --@ AXI like valid; (**Synchronous**, **Active high**) + I_VSpritePipeline_Valid : in std_logic := '0'; --@ Indicates if the sprite is visible in the line. - I_YHitCheck_IsVisible : in std_logic := '0'; + I_VSpritePipeline_IsVisible : in std_logic := '0'; --@ The calculated offset address of the sprite. - I_YHitCheck_Offset : in std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0'); + I_VSpritePipeline_Offset : in std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0'); --@ @end - --@ @virtualbus HorizontalSpritePipeline-Interface @dir Out Interface to the horizontal sprite pipeline + --@ @virtualbus HSpritePipeline-OP @dir Out Horizontal sprite pipeline operation interface --@ AXI like valid; (**Synchronous**, **Active high**) O_HSpritePipeline_Valid : out std_logic := '0'; --@ AXI like ready; (**Synchronous**, **Active high**) @@ -96,71 +96,73 @@ entity OPDecoder is end OPDecoder; architecture RTL of OPDecoder is - signal C_OP_Ready : std_logic := '0'; - + --@ States type for the state machine type T_State is ( S_Ready, S_Dispatch_YHitCheck, S_WaitResponse_YHitCheck, S_Dispatch_CalcPipeline ); + --@ Current state of the state machine signal R_State : T_State := S_Ready; + --@ Next state of the state machine signal C_NextState : T_State := S_Ready; + --@ Operation ready signal + signal C_OP_Ready : std_logic := '0'; + + --@ Write enable signal for the operation data register signal C_OP_Data_WE : std_logic := '0'; + --@ Operation data register signal R_OP_Data : std_logic_vector(G_OPCodeData_Width - 1 downto 0) := (others => '0'); begin - O_OP_Ready <= C_OP_Ready; - - P_RegisterNewLineReq : process (I_CLK) + P_OP_Data_Register : process (I_CLK) begin if rising_edge(I_CLK) then - if I_CE = '1' then - if I_RST = '1' then - R_OP_Data <= (others => '0'); - elsif C_OP_Data_WE = '1' then - R_OP_Data <= I_OP_Data; + if I_RST = '1' then + R_OP_Data <= (others => '0'); + elsif I_CE = '1' then + if C_OP_Data_WE = '1' then + R_OP_Data <= I_OPDecoder_Data; end if; end if; end if; end process; - P_StateForwarding : process (I_CLK) + P_FSM_StateForwarding : process (I_CLK) begin if rising_edge(I_CLK) then - if I_CE = '1' then - if I_RST = '1' then - R_State <= S_Ready; - else - R_State <= C_NextState; - end if; + if I_RST = '1' then + R_State <= S_Ready; + elsif I_CE = '1' then + R_State <= C_NextState; end if; end if; end process; - P_StateMachine : process ( - R_State, I_OP_Code, R_OP_Data, I_OP_Valid, - I_YHitCheck_Ready, I_YHitCheck_Valid, I_YHitCheck_IsVisible, I_YHitCheck_Offset, - I_HSpritePipeline_Ready, I_OP_Data, I_IsVisible + P_FSM : process ( + R_State, I_OPDecoder_Code, R_OP_Data, I_OPDecoder_Valid, + I_VSpritePipeline_Ready, I_VSpritePipeline_Valid, I_VSpritePipeline_IsVisible, I_VSpritePipeline_Offset, + I_HSpritePipeline_Ready, I_OPDecoder_Data, I_RFile_IsVisible ) begin -- Default the next state to the current state C_NextState <= R_State; -- Default the output signals to prevent latches - O_Register_Index_WE <= '0'; - O_Register_Index <= (others => '0'); - O_Register_X_We <= '0'; - O_Register_X <= (others => '0'); - O_Register_Y_WE <= '0'; - O_Register_Y <= (others => '0'); - O_Register_Offset_WE <= '0'; - O_Register_Offset <= (others => '0'); - O_IsVisible_WE <= '0'; - O_IsVisible <= '0'; - O_YHitCheck_Valid <= '0'; - O_YHitCheck_Ready <= '0'; - O_YHitCheck_YToCheck <= (others => '0'); + O_RFile_Wr_Index_WE <= '0'; + O_RFile_Wr_Index <= (others => '0'); + O_RFile_Wr_X_We <= '0'; + O_RFile_Wr_X <= (others => '0'); + O_RFile_Wr_Y_WE <= '0'; + O_RFile_Wr_Y <= (others => '0'); + O_RFile_Wr_Offset_WE <= '0'; + O_RFile_Wr_Offset <= (others => '0'); + O_RFile_Wr_IsVisible_WE <= '0'; + O_RFile_Wr_IsVisible <= '0'; + O_VSpritePipeline_Valid <= '0'; + O_VSpritePipeline_Ready <= '0'; + O_VSpritePipeline_YToCheck <= (others => '0'); C_OP_Ready <= '0'; O_HSpritePipeline_Valid <= '0'; O_HSpritePipeline_X_Request <= (others => '0'); @@ -172,57 +174,57 @@ begin C_OP_Ready <= '1'; C_OP_Data_WE <= '1'; - if I_OP_Valid = '1' then - case I_OP_Code is + if I_OPDecoder_Valid = '1' then + case I_OPDecoder_Code is when K_OP_NOP => C_NextState <= S_Ready; when K_OP_NEWLINE => - O_IsVisible_WE <= '0'; - O_IsVisible <= '0'; + O_RFile_Wr_IsVisible_WE <= '0'; + O_RFile_Wr_IsVisible <= '0'; - C_NextState <= S_Dispatch_YHitCheck; + C_NextState <= S_Dispatch_YHitCheck; when K_OP_SET_ID => - O_Register_Index_WE <= '1'; - O_Register_Index <= I_OP_Data(G_Index_Width - 1 downto 0); + O_RFile_Wr_Index_WE <= '1'; + O_RFile_Wr_Index <= I_OPDecoder_Data(G_Index_Width - 1 downto 0); C_NextState <= S_Ready; when K_OP_SET_X => - O_Register_X_We <= '1'; - O_Register_X <= I_OP_Data(G_X_Width - 1 downto 0); + O_RFile_Wr_X_We <= '1'; + O_RFile_Wr_X <= I_OPDecoder_Data(G_X_Width - 1 downto 0); C_NextState <= S_Ready; when K_OP_SET_Y => - O_Register_Y_WE <= '1'; - O_Register_Y <= I_OP_Data(G_Y_Width - 1 downto 0); + O_RFile_Wr_Y_WE <= '1'; + O_RFile_Wr_Y <= I_OPDecoder_Data(G_Y_Width - 1 downto 0); C_NextState <= S_Ready; when K_OP_REQ_ROW_DATA => - if I_IsVisible = '1' then + if I_RFile_IsVisible = '1' then --@ Only dispatch if the sprite is visible, else drop the request C_NextState <= S_Dispatch_CalcPipeline; end if; when K_OP_CLEAR_ALL => - O_Register_Index_WE <= '1'; - O_Register_Index <= (others => '0'); + O_RFile_Wr_Index_WE <= '1'; + O_RFile_Wr_Index <= (others => '0'); -- - O_Register_X_We <= '1'; - O_Register_X <= (others => '0'); + O_RFile_Wr_X_We <= '1'; + O_RFile_Wr_X <= (others => '0'); -- - O_Register_Y_WE <= '1'; - O_Register_Y <= (others => '0'); + O_RFile_Wr_Y_WE <= '1'; + O_RFile_Wr_Y <= (others => '0'); -- - O_Register_Offset_WE <= '1'; - O_Register_Offset <= (others => '0'); + O_RFile_Wr_Offset_WE <= '1'; + O_RFile_Wr_Offset <= (others => '0'); -- - O_IsVisible_WE <= '1'; - O_IsVisible <= '0'; + O_RFile_Wr_IsVisible_WE <= '1'; + O_RFile_Wr_IsVisible <= '0'; - C_NextState <= S_Ready; + C_NextState <= S_Ready; when others => C_NextState <= S_Ready; @@ -231,24 +233,24 @@ begin end if; when S_Dispatch_YHitCheck => - O_YHitCheck_Valid <= '1'; - O_YHitCheck_YToCheck <= R_OP_Data(G_Y_Width - 1 downto 0); + O_VSpritePipeline_Valid <= '1'; + O_VSpritePipeline_YToCheck <= R_OP_Data(G_Y_Width - 1 downto 0); - if I_YHitCheck_Ready = '1' then + if I_VSpritePipeline_Ready = '1' then C_NextState <= S_WaitResponse_YHitCheck; end if; when S_WaitResponse_YHitCheck => - O_YHitCheck_Ready <= '1'; + O_VSpritePipeline_Ready <= '1'; - if I_YHitCheck_Valid = '1' then - O_IsVisible_WE <= '1'; - O_IsVisible <= I_YHitCheck_IsVisible; + if I_VSpritePipeline_Valid = '1' then + O_RFile_Wr_IsVisible_WE <= '1'; + O_RFile_Wr_IsVisible <= I_VSpritePipeline_IsVisible; - O_Register_Offset_WE <= '1'; - O_Register_Offset <= I_YHitCheck_Offset; + O_RFile_Wr_Offset_WE <= '1'; + O_RFile_Wr_Offset <= I_VSpritePipeline_Offset; - C_NextState <= S_Ready; + C_NextState <= S_Ready; end if; @@ -262,4 +264,5 @@ begin end case; end process; + O_OPDecoder_Ready <= C_OP_Ready; end architecture; diff --git a/src/RegisterFile.vhd b/src/RegisterFile.vhd index 7043165..e1bdcb3 100644 --- a/src/RegisterFile.vhd +++ b/src/RegisterFile.vhd @@ -16,45 +16,45 @@ entity RegisterFile is ); port ( --@ Clock signal; (**Rising edge** triggered) - I_CLK : in std_logic; + I_CLK : in std_logic; --@ Clock enable signal (**Active high**) - I_CE : in std_logic := '1'; + I_CE : in std_logic := '1'; --@ Synchronous reset signal (**Active high**) - I_RST : in std_logic := '0'; + I_RST : in std_logic := '0'; - --@ @virtualbus Register-Write @dir in Bus to write to the register file + --@ @virtualbus Register-Write @dir In Parallel Write to the register file --@ Write enable for the sprite index register; (**Active high**) - I_Index_WE : in std_logic := '0'; + I_RFile_Wr_Index_WE : in std_logic := '0'; --@ Data to write to the sprite index (Base address) register. - I_Index : in std_logic_vector(G_Index_Width - 1 downto 0) := (others => '0'); + I_RFile_Wr_Index : in std_logic_vector(G_Index_Width - 1 downto 0) := (others => '0'); --@ Write enable for the sprite offset (line) register; (**Active high**) - I_Offset_WE : in std_logic := '0'; + I_RFile_Wr_Offset_WE : in std_logic := '0'; --@ Data to write to the sprite offset (Line address) register. - I_Offset : in std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0'); + I_RFile_Wr_Offset : in std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0'); --@ Write enable for the X position register. (**Active high**) - I_X_We : in std_logic := '0'; + I_RFile_Wr_X_We : in std_logic := '0'; --@ Data to write to the X position register (Row) of the sprite. - I_X : in std_logic_vector(G_X_Width - 1 downto 0) := (others => '0'); + I_RFile_Wr_X : in std_logic_vector(G_X_Width - 1 downto 0) := (others => '0'); --@ Write enable for the Y position register. (**Active high**) - I_Y_WE : in std_logic := '0'; + I_RFile_Wr_Y_WE : in std_logic := '0'; --@ Data to write to the Y position register (Line) of the sprite. - I_Y : in std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0'); + I_RFile_Wr_Y : in std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0'); --@ Write enable for the `IsVisible` flag. (**Active high**) - I_IsVisible_WE : in std_logic := '0'; + I_RFile_Wr_IsVisible_WE : in std_logic := '0'; --@ Flag to write to the `IsVisible` flag. - I_IsVisible : in std_logic := '0'; + I_RFile_Wr_IsVisible : in std_logic := '0'; - --@ @virtualbus Register-Read @dir out Bus to read from the register file + --@ @virtualbus Register-Read @dir Out Parallel Read from the register file --@ Sprite index (Base address) of the sprite. - O_Index : out std_logic_vector(G_Index_Width - 1 downto 0) := (others => '0'); + O_RFile_Index : out std_logic_vector(G_Index_Width - 1 downto 0) := (others => '0'); --@ Sprite offset (Line address) of the sprite. - O_Offset : out std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0'); + O_RFile_Offset : out std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0'); --@ X position of the sprite. - O_X : out std_logic_vector(G_X_Width - 1 downto 0) := (others => '0'); + O_RFile_X : out std_logic_vector(G_X_Width - 1 downto 0) := (others => '0'); --@ Y position of the sprite. - O_Y : out std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0'); + O_RFile_Y : out std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0'); --@ Flag to indicate if the sprite line is valid; (**Active high**) - O_IsVisible : out std_logic := '0' + O_RFile_IsVisible : out std_logic := '0' --@ @end ); end entity; @@ -83,24 +83,24 @@ begin R_Y <= (others => '0'); R_IsVisible <= '0'; elsif I_CE = '1' then - if I_Index_WE = '1' then - R_Index <= I_Index; + if I_RFile_Wr_Index_WE = '1' then + R_Index <= I_RFile_Wr_Index; end if; - if I_Offset_WE = '1' then - R_Offset <= I_Offset; + if I_RFile_Wr_Offset_WE = '1' then + R_Offset <= I_RFile_Wr_Offset; end if; - if I_X_We = '1' then - R_X <= I_X; + if I_RFile_Wr_X_We = '1' then + R_X <= I_RFile_Wr_X; end if; - if I_Y_WE = '1' then - R_Y <= I_Y; + if I_RFile_Wr_Y_WE = '1' then + R_Y <= I_RFile_Wr_Y; end if; - if I_IsVisible_WE = '1' then - R_IsVisible <= I_IsVisible; + if I_RFile_Wr_IsVisible_WE = '1' then + R_IsVisible <= I_RFile_Wr_IsVisible; end if; end if; end if; @@ -112,11 +112,11 @@ begin R_IsVisible ) begin - O_Index <= R_Index; - O_Offset <= R_Offset; - O_X <= R_X; - O_Y <= R_Y; - O_IsVisible <= R_IsVisible; + O_RFile_Index <= R_Index; + O_RFile_Offset <= R_Offset; + O_RFile_X <= R_X; + O_RFile_Y <= R_Y; + O_RFile_IsVisible <= R_IsVisible; end process; end architecture; diff --git a/src/SpriteChannel.ucf b/src/SpriteChannel.ucf index 72e670e..a076f5b 100644 --- a/src/SpriteChannel.ucf +++ b/src/SpriteChannel.ucf @@ -2,4 +2,4 @@ NET I_CLK LOC = B8; NET I_CLK TNM_NET = CLOCK; -TIMESPEC TS_CLOCK = PERIOD CLOCK 230 MHz HIGH 50 %; \ No newline at end of file +TIMESPEC TS_CLOCK = PERIOD CLOCK 220 MHz HIGH 50 %; \ No newline at end of file diff --git a/src/SpriteChannel.vhd b/src/SpriteChannel.vhd index f3bdd18..78f42c0 100644 --- a/src/SpriteChannel.vhd +++ b/src/SpriteChannel.vhd @@ -8,116 +8,100 @@ entity SpriteChannel is --@ Data width of the operation data. G_OPCodeData_Width : integer := 10; --@ Width of the sprite index (Base address) register - G_Index_Width : integer := 5; + G_Index_Width : integer := 5; --@ Width of the sprite offset (Line address) register - G_Offset_Width : integer := 8; + G_Offset_Width : integer := 8; + --@ Width of the pixel data output + G_Pixel_Width : integer := 8; --@ Width of the X position (Row) register - G_X_Width : integer := 10; + G_X_Width : integer := 10; --@ Width of the Y position (Line) register - G_Y_Width : integer := 10; + G_Y_Width : integer := 10; --@ The height of the sprite in pixels - G_Sprite_Height : integer := 16; + G_Sprite_Height : integer := 16; --@ The width of the sprite in pixels - G_Sprite_Width : integer := 16 + G_Sprite_Width : integer := 16 ); port ( --@ Clock signal; **Rising edge** triggered - I_CLK : in std_logic; + I_CLK : in std_logic; --@ Clock Enable signal - I_CE : in std_logic; + I_CE : in std_logic; --@ Synchronous reset signal - I_RST : in std_logic; + I_RST : in std_logic; --@ @virtualbus Operation-Write @dir in Operation Write Interface --@ Indicates if the `OPCode` and `OPData` are valid. (**Active high**) - I_OP_Valid : in std_logic := '0'; + I_OP_Valid : in std_logic := '0'; --@ Indicates if the decoder is ready to accept data. (**Active high**) - O_OP_Ready : out std_logic := '0'; + O_OP_Ready : out std_logic := '0'; --@ Operation code for the sprite channel - I_OP_Code : in std_logic_vector(3 downto 0) := (others => '0'); + I_OP_Code : in std_logic_vector(3 downto 0) := (others => '0'); --@ Data to be used with the operation code. - I_OP_Data : in std_logic_vector(G_OPCodeData_Width - 1 downto 0) := (others => '0'); + I_OP_Data : in std_logic_vector(G_OPCodeData_Width - 1 downto 0) := (others => '0'); + --@ @end + + --@ @virtualbus Address-Port-0 @dir in Address Port 0 + O_Rom_Address_Valid : out std_logic := '0'; + I_Rom_Address_Ready : in std_logic := '0'; + O_Rom_Address : out std_logic_vector(G_Index_Width + G_Offset_Width - 1 downto 0) := (others => '0'); + --@ @end + + --@ @virtualbus Data-Port-0 @dir out Data Port 0 + I_Rom_Data_Valid : in std_logic := '0'; + O_Rom_Data_Ready : out std_logic := '0'; + I_Rom_Data : in std_logic_vector(G_Pixel_Width - 1 downto 0) := (others => '0'); --@ @end --@ @virtualbus Pixel-Data @dir Out Pixel data output bus --@ AXI like valid; (**Synchronous**, **Active high**) - O_Pixel_Valid : out std_logic; + O_Pixel_Valid : out std_logic; --@ AXI like ready; (**Synchronous**, **Active high**) - I_Pixel_Ready : in std_logic; + I_Pixel_Ready : in std_logic; --@ Pixel data - O_Pixel_Data : out std_logic_vector(7 downto 0) + O_Pixel_Data : out std_logic_vector(7 downto 0) --@ @end ); end entity; architecture RTL of SpriteChannel is - signal R_Index : std_logic_vector(G_Index_Width - 1 downto 0) := (others => '0'); - signal R_Offset : std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0'); - signal R_X : std_logic_vector(G_X_Width - 1 downto 0) := (others => '0'); - signal R_Y : std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0'); - signal R_IsVisible : std_logic := '0'; + -- Register file signals -- + signal I_RFile_Wr_Index_WE : std_logic := '0'; + signal I_RFile_Wr_Index : std_logic_vector(G_Index_Width - 1 downto 0) := (others => '0'); + signal I_RFile_Wr_Offset_WE : std_logic := '0'; + signal I_RFile_Wr_Offset : std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0'); + signal I_RFile_Wr_X_We : std_logic := '0'; + signal I_RFile_Wr_X : std_logic_vector(G_X_Width - 1 downto 0) := (others => '0'); + signal I_RFile_Wr_Y_WE : std_logic := '0'; + signal I_RFile_Wr_Y : std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0'); + signal I_RFile_Wr_IsVisible_WE : std_logic := '0'; + signal I_RFile_Wr_IsVisible : std_logic := '0'; + ------------------------ + signal O_RFile_Index : std_logic_vector(G_Index_Width - 1 downto 0) := (others => '0'); + signal O_RFile_Offset : std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0'); + signal O_RFile_X : std_logic_vector(G_X_Width - 1 downto 0) := (others => '0'); + signal O_RFile_Y : std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0'); + signal O_RFile_IsVisible : std_logic := '0'; - signal OI_P0_Address_Valid : std_logic := '0'; - signal IO_P0_Address_Ready : std_logic := '0'; - signal OI_P0_Address : std_logic_vector(G_Index_Width + G_Offset_Width - 1 downto 0) := (others => '0'); + -- Vertical sprite pipeline signals -- + signal O_VSpritePipeline_OP_Ready : std_logic := '0'; + signal I_VSpritePipeline_OP_Valid : std_logic := '0'; + signal I_VSpritePipeline_OP_Y_Request : std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0'); + ------------------------ + signal I_VSpritePipeline_Ready : std_logic := '0'; + signal O_VSpritePipeline_Valid : std_logic := '0'; + signal O_VSpritePipeline_IsVisible : std_logic := '0'; + signal O_VSpritePipeline_Offset : std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0'); - signal IO_P0_Data_Valid : std_logic := '0'; - signal OI_P0_Data_Ready : std_logic := '0'; - signal IO_P0_Data : std_logic_vector(7 downto 0) := (others => '0'); + -- Horizontal sprite pipeline signals -- + signal I_HSpritePipeline_OP_Valid : std_logic; + signal O_HSpritePipeline_OP_Ready : std_logic; + signal I_HSpritePipeline_OP_X_Request : std_logic_vector(G_X_Width - 1 downto 0); - signal OI_Register_Index_WE : std_logic := '0'; - signal OI_Register_Index : std_logic_vector(G_Index_Width - 1 downto 0) := (others => '0'); - signal OI_Register_Offset_WE : std_logic := '0'; - signal OI_Register_Offset : std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0'); - signal OI_Register_X_We : std_logic := '0'; - signal OI_Register_X : std_logic_vector(G_X_Width - 1 downto 0) := (others => '0'); - signal OI_Register_Y_WE : std_logic := '0'; - signal OI_Register_Y : std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0'); - signal OI_IsVisible_WE : std_logic := '0'; - signal OI_IsVisible : std_logic := '0'; - - signal I_YHitCheck_Ready : std_logic := '0'; - signal I_YHitCheck_Valid : std_logic := '0'; - signal I_YHitCheck_IsVisible : std_logic := '0'; - signal I_YHitCheck_Offset : std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0'); - signal O_YHitCheck_Valid : std_logic := '0'; - signal O_YHitCheck_YToCheck : std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0'); - signal O_YHitCheck_Ready : std_logic := '0'; - - signal OI_CalcPipeline_Valid : std_logic := '0'; - signal IO_CalcPipeline_Ready : std_logic := '0'; - signal OI_CalcPipeline_X_Request : std_logic_vector(G_X_Width - 1 downto 0) := (others => '0'); begin - i_RegisterFile : entity work.RegisterFile - generic map( - G_Index_Width => G_Index_Width, - G_Offset_Width => G_Offset_Width, - G_X_Width => G_X_Width, - G_Y_Width => G_Y_Width - ) - port map( - I_CLK => I_CLK, - I_CE => I_CE, - I_RST => I_RST, - I_Index_WE => OI_Register_Index_WE, - I_Index => OI_Register_Index, - I_Offset_WE => OI_Register_Offset_WE, - I_Offset => OI_Register_Offset, - I_X_We => OI_Register_X_We, - I_X => OI_Register_X, - I_Y_WE => OI_Register_Y_WE, - I_Y => OI_Register_Y, - I_IsVisible_WE => OI_IsVisible_WE, - I_IsVisible => OI_IsVisible, - O_Index => R_Index, - O_Offset => R_Offset, - O_X => R_X, - O_Y => R_Y, - O_IsVisible => R_IsVisible - ); - i_OPDecoder : entity work.OPDecoder + INST_OPDecoder : entity work.OPDecoder generic map( G_OPCodeData_Width => G_OPCodeData_Width, G_Index_Width => G_Index_Width, @@ -126,107 +110,110 @@ begin G_Y_Width => G_Y_Width ) port map( - I_CLK => I_CLK, - I_CE => I_CE, - I_RST => I_RST, - I_OP_Valid => I_OP_Valid, - O_OP_Ready => O_OP_Ready, - I_OP_Code => I_OP_Code, - I_OP_Data => I_OP_Data, - O_Register_Index_WE => OI_Register_Index_WE, - O_Register_Index => OI_Register_Index, - O_Register_Offset_WE => OI_Register_Offset_WE, - O_Register_Offset => OI_Register_Offset, - O_Register_X_We => OI_Register_X_We, - O_Register_X => OI_Register_X, - O_Register_Y_WE => OI_Register_Y_WE, - O_Register_Y => OI_Register_Y, - O_IsVisible_WE => OI_IsVisible_WE, - O_IsVisible => OI_IsVisible, - - I_IsVisible => R_IsVisible, - - I_YHitCheck_Ready => I_YHitCheck_Ready, - O_YHitCheck_Valid => O_YHitCheck_Valid, - O_YHitCheck_YToCheck => O_YHitCheck_YToCheck, - O_YHitCheck_Ready => O_YHitCheck_Ready, - I_YHitCheck_Valid => I_YHitCheck_Valid, - I_YHitCheck_IsVisible => I_YHitCheck_IsVisible, - I_YHitCheck_Offset => I_YHitCheck_Offset, - - O_HSpritePipeline_Valid => OI_CalcPipeline_Valid, - I_HSpritePipeline_Ready => IO_CalcPipeline_Ready, - O_HSpritePipeline_X_Request => OI_CalcPipeline_X_Request + I_CLK => I_CLK, + I_CE => I_CE, + I_RST => I_RST, + I_OPDecoder_Valid => I_OP_Valid, + O_OPDecoder_Ready => O_OP_Ready, + I_OPDecoder_Code => I_OP_Code, + I_OPDecoder_Data => I_OP_Data, + O_RFile_Wr_Index_WE => I_RFile_Wr_Index_WE, + O_RFile_Wr_Index => I_RFile_Wr_Index, + O_RFile_Wr_Offset_WE => I_RFile_Wr_Offset_WE, + O_RFile_Wr_Offset => I_RFile_Wr_Offset, + O_RFile_Wr_X_We => I_RFile_Wr_X_We, + O_RFile_Wr_X => I_RFile_Wr_X, + O_RFile_Wr_Y_WE => I_RFile_Wr_Y_WE, + O_RFile_Wr_Y => I_RFile_Wr_Y, + O_RFile_Wr_IsVisible_WE => I_RFile_Wr_IsVisible_WE, + O_RFile_Wr_IsVisible => I_RFile_Wr_IsVisible, + I_RFile_IsVisible => O_RFile_IsVisible, + I_VSpritePipeline_Ready => O_VSpritePipeline_OP_Ready, + O_VSpritePipeline_Valid => I_VSpritePipeline_OP_Valid, + O_VSpritePipeline_YToCheck => I_VSpritePipeline_OP_Y_Request, + O_VSpritePipeline_Ready => I_VSpritePipeline_Ready, + I_VSpritePipeline_Valid => O_VSpritePipeline_Valid, + I_VSpritePipeline_IsVisible => O_VSpritePipeline_IsVisible, + I_VSpritePipeline_Offset => O_VSpritePipeline_Offset, + O_HSpritePipeline_Valid => I_HSpritePipeline_OP_Valid, + I_HSpritePipeline_Ready => O_HSpritePipeline_OP_Ready, + O_HSpritePipeline_X_Request => I_HSpritePipeline_OP_X_Request ); - i_YHitCheck : entity work.VerticalSpritePipeline - generic map( - G_Y_Width => G_Y_Width, - G_Sprite_Height => G_Sprite_Height, - G_Offset_Width => G_Offset_Width, - G_PipelineStages => 2 - ) - port map( - I_CLK => I_CLK, - I_CE => I_CE, - O_Ready => I_YHitCheck_Ready, - I_Valid => O_YHitCheck_Valid, - I_YToCheck => O_YHitCheck_YToCheck, - I_Y => R_Y, - I_Ready => O_YHitCheck_Ready, - O_Valid => I_YHitCheck_Valid, - O_IsVisible => I_YHitCheck_IsVisible, - O_Offset => I_YHitCheck_Offset - ); - - i_Rom : entity work.Rom - generic map( - G_Address_Width => 13, - G_Data_Width => 8, - G_P0_BufferStages => 1, - G_P0_ID_Width => 0, - G_P1_BufferStages => 0, - G_P1_ID_Width => 0, - G_RomType => "Block" - ) - port map( - I_CLK => I_CLK, - I_CE => I_CE, - I_P0_Address_Valid => OI_P0_Address_Valid, - O_P0_Address_Ready => IO_P0_Address_Ready, - I_P0_Address => OI_P0_Address, - O_P0_Data_Valid => IO_P0_Data_Valid, - I_P0_Data_Ready => OI_P0_Data_Ready, - O_P0_Data => IO_P0_Data - ); - - i_CalcPipeline : entity work.HorizontalSpritePipeline + INST_RFile : entity work.RegisterFile generic map( G_Index_Width => G_Index_Width, G_Offset_Width => G_Offset_Width, G_X_Width => G_X_Width, - G_Rom_Width => 8, - G_Pixel_Width => 8 + G_Y_Width => G_Y_Width ) port map( - I_CLK => I_CLK, - I_CE => I_CE, - I_RST => I_RST, - I_OP_Valid => OI_CalcPipeline_Valid, - O_OP_Ready => IO_CalcPipeline_Ready, - I_OP_X_Request => OI_CalcPipeline_X_Request, - I_OP_Index => R_Index, - I_OP_Offset => R_Offset, - I_OP_X_Sprite => R_X, - O_Rom_Valid => OI_P0_Address_Valid, - I_Rom_Ready => IO_P0_Address_Ready, - O_Rom_Address => OI_P0_Address, - I_Rom_Valid => IO_P0_Data_Valid, - O_Rom_Ready => OI_P0_Data_Ready, - I_Rom_Data => IO_P0_Data, - O_Pixel_Valid => O_Pixel_Valid, - I_Pixel_Ready => I_Pixel_Ready, - O_Pixel_Data => O_Pixel_Data + I_CLK => I_CLK, + I_CE => I_CE, + I_RST => I_RST, + I_RFile_Wr_Index_WE => I_RFile_Wr_Index_WE, + I_RFile_Wr_Index => I_RFile_Wr_Index, + I_RFile_Wr_Offset_WE => I_RFile_Wr_Offset_WE, + I_RFile_Wr_Offset => I_RFile_Wr_Offset, + I_RFile_Wr_X_We => I_RFile_Wr_X_We, + I_RFile_Wr_X => I_RFile_Wr_X, + I_RFile_Wr_Y_WE => I_RFile_Wr_Y_WE, + I_RFile_Wr_Y => I_RFile_Wr_Y, + I_RFile_Wr_IsVisible_WE => I_RFile_Wr_IsVisible_WE, + I_RFile_Wr_IsVisible => I_RFile_Wr_IsVisible, + O_RFile_Index => O_RFile_Index, + O_RFile_Offset => O_RFile_Offset, + O_RFile_X => O_RFile_X, + O_RFile_Y => O_RFile_Y, + O_RFile_IsVisible => O_RFile_IsVisible + ); + + INST_VSpritePipeline : entity work.VerticalSpritePipeline + generic map( + G_Y_Width => G_Y_Width, + G_Sprite_Height => G_Sprite_Height, + G_Offset_Width => G_Offset_Width + ) + port map( + I_CLK => I_CLK, + I_CE => I_CE, + O_VSpritePipeline_OP_Ready => O_VSpritePipeline_OP_Ready, + I_VSpritePipeline_OP_Valid => I_VSpritePipeline_OP_Valid, + I_VSpritePipeline_OP_Y_Request => I_VSpritePipeline_OP_Y_Request, + I_VSpritePipeline_OP_Y_Sprite => O_RFile_Y, + I_VSpritePipeline_Ready => I_VSpritePipeline_Ready, + O_VSpritePipeline_Valid => O_VSpritePipeline_Valid, + O_VSpritePipeline_IsVisible => O_VSpritePipeline_IsVisible, + O_VSpritePipeline_Offset => O_VSpritePipeline_Offset + ); + + INST_HSpritePipeline : entity work.HorizontalSpritePipeline + generic map( + G_Index_Width => G_Index_Width, + G_Offset_Width => G_Offset_Width, + G_X_Width => G_X_Width, + G_Pixel_Width => G_Pixel_Width, + G_Sprite_MaxWidth => G_Sprite_Width + ) + port map( + I_CLK => I_CLK, + I_CE => I_CE, + I_RST => I_RST, + I_HSpritePipeline_OP_Valid => I_HSpritePipeline_OP_Valid, + O_HSpritePipeline_OP_Ready => O_HSpritePipeline_OP_Ready, + I_HSpritePipeline_OP_Index => O_RFile_Index, + I_HSpritePipeline_OP_Offset => O_RFile_Offset, + I_HSpritePipeline_OP_X_Request => I_HSpritePipeline_OP_X_Request, + I_HSpritePipeline_OP_X_Sprite => O_RFile_X, + O_Rom_Valid => O_Rom_Address_Valid, + I_Rom_Ready => I_Rom_Address_Ready, + O_Rom_Address => O_Rom_Address, + I_Rom_Valid => I_Rom_Data_Valid, + O_Rom_Ready => O_Rom_Data_Ready, + I_Rom_Data => I_Rom_Data, + O_Pixel_Valid => O_Pixel_Valid, + I_Pixel_Ready => I_Pixel_Ready, + O_Pixel_Data => O_Pixel_Data ); end architecture RTL; diff --git a/test/OPDecoder_tb.vhd b/test/OPDecoder_tb.vhd index a83bff9..b782ba3 100644 --- a/test/OPDecoder_tb.vhd +++ b/test/OPDecoder_tb.vhd @@ -9,17 +9,17 @@ end entity OPDecoder_tb; architecture bench of OPDecoder_tb is -- Clock period - constant K_CLKPeriod : time := 10 ns; + constant K_CLKPeriod : time := 10 ns; -- Generics - constant G_OPCodeData_Width : integer := 10; - constant G_ROM_DataWidth : integer := 16; - constant G_Index_Width : integer := 6; - constant G_Offset_Width : integer := 4; - constant G_LineData_Width : integer := 16; - constant G_X_Width : integer := 10; - constant G_Y_Width : integer := 10; - constant G_Sprite_Height : integer := 16; - constant G_PipelineStages : integer := 2; + constant G_OPCodeData_Width : integer := 10; + constant G_ROM_DataWidth : integer := 16; + constant G_Index_Width : integer := 6; + constant G_Offset_Width : integer := 4; + constant G_LineData_Width : integer := 16; + constant G_X_Width : integer := 10; + constant G_Y_Width : integer := 10; + constant G_Sprite_Height : integer := 16; + constant G_PipelineStages : integer := 2; -- Ports signal I_CLK : std_logic; @@ -57,9 +57,9 @@ architecture bench of OPDecoder_tb is signal I_CalcPipeline_Ready : std_logic := '0'; signal O_CalcPipeline_X : std_logic_vector(G_X_Width - 1 downto 0) := (others => '0'); - signal R1, R2 : std_logic := '0'; + signal R1, R2 : std_logic := '0'; - signal TestDone : boolean := false; + signal TestDone : boolean := false; begin ClockProc : process @@ -90,29 +90,29 @@ begin I_CLK => I_CLK, I_CE => I_CE, I_RST => I_RST, - I_OP_Valid => I_OP_Valid, - O_OP_Ready => O_OP_Ready, - I_OP_Code => I_OP_Code, - I_OP_Data => I_OP_Data, - O_Register_Index_WE => O_Register_Index_WE, - O_Register_Index => O_Register_Index, - O_Register_Offset_WE => O_Register_Offset_WE, - O_Register_Offset => O_Register_Offset, - O_Register_X_We => O_Register_X_We, - O_Register_X => O_Register_X, - O_Register_Y_WE => O_Register_Y_WE, - O_Register_Y => O_Register_Y, + I_OPDecoder_Valid => I_OP_Valid, + O_OPDecoder_Ready => O_OP_Ready, + I_OPDecoder_Code => I_OP_Code, + I_OPDecoder_Data => I_OP_Data, + O_RFile_Wr_Index_WE => O_Register_Index_WE, + O_RFile_Wr_Index => O_Register_Index, + O_RFile_Wr_Offset_WE => O_Register_Offset_WE, + O_RFile_Wr_Offset => O_Register_Offset, + O_RFile_Wr_X_We => O_Register_X_We, + O_RFile_Wr_X => O_Register_X, + O_RFile_Wr_Y_WE => O_Register_Y_WE, + O_RFile_Wr_Y => O_Register_Y, O_Register_CachedLineData_WE => O_Register_CachedLineData_WE, O_Register_CachedLineData => O_Register_CachedLineData, O_Register_CacheValid_WE => O_Register_CacheValid_WE, O_Register_CacheValid => O_Register_CacheValid, - I_YHitCheck_Ready => I_YHitCheck_Ready, - O_YHitCheck_Valid => O_YHitCheck_Valid, - O_YHitCheck_YToCheck => O_YHitCheck_YToCheck, - O_YHitCheck_Ready => O_YHitCheck_Ready, - I_YHitCheck_Valid => I_YHitCheck_Valid, - I_YHitCheck_IsVisible => I_YHitCheck_IsVisible, - I_YHitCheck_Offset => I_YHitCheck_Offset, + I_VSpritePipeline_Ready => I_YHitCheck_Ready, + O_VSpritePipeline_Valid => O_YHitCheck_Valid, + O_VSpritePipeline_YToCheck => O_YHitCheck_YToCheck, + O_VSpritePipeline_Ready => O_YHitCheck_Ready, + I_VSpritePipeline_Valid => I_YHitCheck_Valid, + I_VSpritePipeline_IsVisible => I_YHitCheck_IsVisible, + I_VSpritePipeline_Offset => I_YHitCheck_Offset, O_Rom_Valid => O_Rom_Valid, I_Rom_Ready => I_Rom_Ready, I_Rom_Valid => I_Rom_Valid, @@ -133,16 +133,16 @@ begin G_PipelineStages => G_PipelineStages ) port map( - I_CLK => I_CLK, - I_CE => I_CE, - O_Ready => I_YHitCheck_Ready, - I_Valid => O_YHitCheck_Valid, - I_YToCheck => O_YHitCheck_YToCheck, - I_Y => "0000000000", - I_Ready => O_YHitCheck_Ready, - O_Valid => I_YHitCheck_Valid, - O_IsVisible => I_YHitCheck_IsVisible, - O_Offset => I_YHitCheck_Offset + I_CLK => I_CLK, + I_CE => I_CE, + O_VSpritePipeline_OP_Ready => I_YHitCheck_Ready, + I_VSpritePipeline_OP_Valid => O_YHitCheck_Valid, + I_VSpritePipeline_OP_Y_Request => O_YHitCheck_YToCheck, + I_VSpritePipeline_OP_Y_Sprite => "0000000000", + I_VSpritePipeline_Ready => O_YHitCheck_Ready, + O_VSpritePipeline_Valid => I_YHitCheck_Valid, + O_VSpritePipeline_IsVisible => I_YHitCheck_IsVisible, + O_VSpritePipeline_Offset => I_YHitCheck_Offset ); StimulusProc : process diff --git a/test/YHitCheck_tb.vhd b/test/YHitCheck_tb.vhd index f222121..2aa75e9 100644 --- a/test/YHitCheck_tb.vhd +++ b/test/YHitCheck_tb.vhd @@ -9,21 +9,21 @@ end; architecture bench of YHitCheck_tb is -- Clock period - constant K_CLKPeriod : time := 10 ns; + constant K_CLKPeriod : time := 10 ns; -- Generics - constant G_YWidth : integer := 10; - constant G_SpriteHeight : integer := 16; + constant G_YWidth : integer := 10; + constant G_SpriteHeight : integer := 16; -- Ports - signal I_CLK : std_logic := '0'; - signal I_CE : std_logic; - signal O_Ready : std_logic; - signal I_Valid : std_logic; - signal I_YToCheck : std_logic_vector(G_YWidth - 1 downto 0); - signal I_Y : std_logic_vector(G_YWidth - 1 downto 0); - signal I_Ready : std_logic; - signal O_Valid : std_logic; - signal O_IsVisible : std_logic; - signal O_Offset : std_logic_vector(7 downto 0); + signal I_CLK : std_logic := '0'; + signal I_CE : std_logic; + signal O_Ready : std_logic; + signal I_Valid : std_logic; + signal I_YToCheck : std_logic_vector(G_YWidth - 1 downto 0); + signal I_Y : std_logic_vector(G_YWidth - 1 downto 0); + signal I_Ready : std_logic; + signal O_Valid : std_logic; + signal O_IsVisible : std_logic; + signal O_Offset : std_logic_vector(7 downto 0); type T_TestData is record YToCheck : integer; @@ -86,16 +86,16 @@ begin G_Sprite_Height => G_SpriteHeight ) port map( - I_CLK => I_CLK, - I_CE => I_CE, - O_Ready => O_Ready, - I_Valid => I_Valid, - I_YToCheck => I_YToCheck, - I_Y => I_Y, - I_Ready => I_Ready, - O_Valid => O_Valid, - O_IsVisible => O_IsVisible, - O_Offset => O_Offset + I_CLK => I_CLK, + I_CE => I_CE, + O_VSpritePipeline_OP_Ready => O_Ready, + I_VSpritePipeline_OP_Valid => I_Valid, + I_VSpritePipeline_OP_Y_Request => I_YToCheck, + I_VSpritePipeline_OP_Y_Sprite => I_Y, + I_VSpritePipeline_Ready => I_Ready, + O_VSpritePipeline_Valid => O_Valid, + O_VSpritePipeline_IsVisible => O_IsVisible, + O_VSpritePipeline_Offset => O_Offset ); StimulusProc : process