Test
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1 @@
|
|||||||
.locale/
|
.locale/
|
||||||
build/
|
|
2
build/.gitignore
vendored
Normal file
2
build/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
working/
|
||||||
|
reports/
|
24
build/LICENSE.md
Normal file
24
build/LICENSE.md
Normal file
@@ -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 <http://unlicense.org>
|
275
build/Makefile
Normal file
275
build/Makefile
Normal file
@@ -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
|
||||||
|
|
||||||
|
###########################################################################
|
225
build/README.md
Normal file
225
build/README.md
Normal file
@@ -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.
|
110
build/project.cfg.sample
Normal file
110
build/project.cfg.sample
Normal file
@@ -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
|
||||||
|
|
||||||
|
## ## ## ## ## ## ## ##
|
||||||
|
# ---------------------
|
16
project.cfg
16
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/PipelineController.vhd
|
||||||
VHDSOURCE += ../Asynchronous-FIFO-AXI-Handshake/libs/Pipeline-AXI-Handshake/src/PipelineStage.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 += ../Asynchronous-FIFO-AXI-Handshake/libs/Pipeline-AXI-Handshake/src/PipelineFilter.vhd
|
||||||
VHDSOURCE += libs/PriorityEncoders.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_2.vhdl
|
||||||
VHDSOURCE += libs/AXI-HS-Scheduler/build/AXI_Handshaking_Scheduler_4.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_8.vhdl
|
||||||
VHDSOURCE += libs/AXI-HS-Scheduler/build/AXI_Handshaking_Scheduler_16.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_32.vhdl
|
||||||
VHDSOURCE += libs/AXI-HS-Scheduler/build/AXI_Handshaking_Scheduler_64.vhdl
|
# VHDSOURCE += libs/AXI-HS-Scheduler/build/AXI_Handshaking_Scheduler_64.vhdl
|
||||||
VHDSOURCE += libs/AXI-HS-MUX/AXI_HS_MUX.vhd
|
# VHDSOURCE += libs/AXI-HS-MUX/AXI_HS_MUX.vhd
|
||||||
VHDSOURCE += libs/OPCodes.vhd
|
VHDSOURCE += libs/OPCodes.vhd
|
||||||
|
|
||||||
VHDSOURCE += src/VerticalSpritePipeline.vhd
|
VHDSOURCE += src/VerticalSpritePipeline.vhd
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
--@ address and color data.
|
--@ address and color data.
|
||||||
--@
|
--@
|
||||||
--@ The operation is fully pipelined and includes the following steps:
|
--@ 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
|
--@ - Calculation of the horizontal offset between request and sprite position
|
||||||
--@ - Visibility check against the maximum sprite width
|
--@ - Visibility check against the maximum sprite width
|
||||||
--@ - ROM address generation for the sprite pixel
|
--@ - ROM address generation for the sprite pixel
|
||||||
@@ -31,66 +31,64 @@ use ieee.math_real.all;
|
|||||||
entity HorizontalSpritePipeline is
|
entity HorizontalSpritePipeline is
|
||||||
generic (
|
generic (
|
||||||
--@ Width of the sprite index (Base address) register
|
--@ 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
|
--@ 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
|
--@ Width of the X position (Row) register
|
||||||
G_X_Width : integer := 10;
|
G_X_Width : integer := 10;
|
||||||
--@ Width of the pixel data from rom
|
|
||||||
G_Rom_Width : integer := 8;
|
|
||||||
--@ Width of the pixel data output
|
--@ Width of the pixel data output
|
||||||
G_Pixel_Width : integer := 8;
|
G_Pixel_Width : integer := 8;
|
||||||
--@ Horizontal width of a sprite in pixels
|
--@ Horizontal width of a sprite in pixels
|
||||||
G_SpriteMaxWidth : integer := 16
|
G_Sprite_MaxWidth : integer := 16
|
||||||
);
|
);
|
||||||
port (
|
port (
|
||||||
--@ Clock; (**Rising edge** triggered)
|
--@ Clock; (**Rising edge** triggered)
|
||||||
I_CLK : in std_logic;
|
I_CLK : in std_logic;
|
||||||
--@ Clock Enable; (**Synchronous**, **Active high**)
|
--@ Clock Enable; (**Synchronous**, **Active high**)
|
||||||
I_CE : in std_logic;
|
I_CE : in std_logic;
|
||||||
--@ Reset; (**Synchronous**, **Active high**)
|
--@ Reset; (**Synchronous**, **Active high**)
|
||||||
I_RST : in std_logic;
|
I_RST : in std_logic;
|
||||||
|
|
||||||
--@ @virtualbus Operation @dir In Operation input bus
|
--@ @virtualbus Operation @dir In Operation input bus
|
||||||
--@ AXI like valid; (**Synchronous**, **Active high**)
|
--@ 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**)
|
--@ AXI like ready; (**Synchronous**, **Active high**)
|
||||||
O_OP_Ready : out std_logic;
|
O_HSpritePipeline_OP_Ready : out std_logic;
|
||||||
--@ Index address
|
--@ 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
|
--@ 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
|
--@ 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
|
--@ 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
|
--@ @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**)
|
--@ AXI like valid; (**Synchronous**, **Active high**)
|
||||||
O_Rom_Valid : out std_logic;
|
O_Rom_Valid : out std_logic;
|
||||||
--@ AXI like ready; (**Synchronous**, **Active high**)
|
--@ AXI like ready; (**Synchronous**, **Active high**)
|
||||||
I_Rom_Ready : in std_logic;
|
I_Rom_Ready : in std_logic;
|
||||||
--@ Rom address
|
--@ 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
|
--@ @end
|
||||||
|
|
||||||
--@ @virtualbus Rom-Data @dir In Rom data bus
|
--@ @virtualbus Rom-Data @dir In Rom data bus
|
||||||
--@ AXI like valid; (**Synchronous**, **Active high**)
|
--@ AXI like valid; (**Synchronous**, **Active high**)
|
||||||
I_Rom_Valid : in std_logic;
|
I_Rom_Valid : in std_logic;
|
||||||
--@ AXI like ready; (**Synchronous**, **Active high**)
|
--@ AXI like ready; (**Synchronous**, **Active high**)
|
||||||
O_Rom_Ready : out std_logic;
|
O_Rom_Ready : out std_logic;
|
||||||
--@ Rom data
|
--@ 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
|
--@ @end
|
||||||
|
|
||||||
--@ @virtualbus Pixel-Data @dir Out Pixel data output bus
|
--@ @virtualbus Pixel-Data @dir Out Pixel data bus
|
||||||
--@ AXI like valid; (**Synchronous**, **Active high**)
|
--@ AXI like valid; (**Synchronous**, **Active high**)
|
||||||
O_Pixel_Valid : out std_logic;
|
O_Pixel_Valid : out std_logic;
|
||||||
--@ AXI like ready; (**Synchronous**, **Active high**)
|
--@ AXI like ready; (**Synchronous**, **Active high**)
|
||||||
I_Pixel_Ready : in std_logic;
|
I_Pixel_Ready : in std_logic;
|
||||||
--@ Pixel data
|
--@ 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
|
||||||
);
|
);
|
||||||
end entity HorizontalSpritePipeline;
|
end entity HorizontalSpritePipeline;
|
||||||
@@ -142,8 +140,8 @@ begin
|
|||||||
I_CLK => I_CLK,
|
I_CLK => I_CLK,
|
||||||
I_CE => I_CE,
|
I_CE => I_CE,
|
||||||
O_Enable => O_HSpritePipelineCtrl_Enable,
|
O_Enable => O_HSpritePipelineCtrl_Enable,
|
||||||
I_Valid => I_OP_Valid,
|
I_Valid => I_HSpritePipeline_OP_Valid,
|
||||||
O_Ready => O_OP_Ready,
|
O_Ready => O_HSpritePipeline_OP_Ready,
|
||||||
O_Valid => O_HSpritePipeline_Valid,
|
O_Valid => O_HSpritePipeline_Valid,
|
||||||
I_Ready => I_HSpritePipeline_Ready
|
I_Ready => I_HSpritePipeline_Ready
|
||||||
);
|
);
|
||||||
@@ -157,7 +155,7 @@ begin
|
|||||||
port map(
|
port map(
|
||||||
I_CLK => I_CLK,
|
I_CLK => I_CLK,
|
||||||
I_Enable => O_HSpritePipelineCtrl_Enable,
|
I_Enable => O_HSpritePipelineCtrl_Enable,
|
||||||
I_Data => I_OP_Index,
|
I_Data => I_HSpritePipeline_OP_Index,
|
||||||
O_Data => R_Index
|
O_Data => R_Index
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -170,7 +168,7 @@ begin
|
|||||||
port map(
|
port map(
|
||||||
I_CLK => I_CLK,
|
I_CLK => I_CLK,
|
||||||
I_Enable => O_HSpritePipelineCtrl_Enable,
|
I_Enable => O_HSpritePipelineCtrl_Enable,
|
||||||
I_Data => I_OP_Offset,
|
I_Data => I_HSpritePipeline_OP_Offset,
|
||||||
O_Data => R_Offset
|
O_Data => R_Offset
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -183,7 +181,7 @@ begin
|
|||||||
port map(
|
port map(
|
||||||
I_CLK => I_CLK,
|
I_CLK => I_CLK,
|
||||||
I_Enable => O_HSpritePipelineCtrl_Enable,
|
I_Enable => O_HSpritePipelineCtrl_Enable,
|
||||||
I_Data => I_OP_X_Request,
|
I_Data => I_HSpritePipeline_OP_X_Request,
|
||||||
O_Data => R_X_Request
|
O_Data => R_X_Request
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -196,7 +194,7 @@ begin
|
|||||||
port map(
|
port map(
|
||||||
I_CLK => I_CLK,
|
I_CLK => I_CLK,
|
||||||
I_Enable => O_HSpritePipelineCtrl_Enable,
|
I_Enable => O_HSpritePipelineCtrl_Enable,
|
||||||
I_Data => I_OP_X_Sprite,
|
I_Data => I_HSpritePipeline_OP_X_Sprite,
|
||||||
O_Data => R_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))
|
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';
|
'0';
|
||||||
|
|
||||||
INST_HSpritePipeline_Address : entity work.PipelineRegister
|
INST_HSpritePipeline_Address : entity work.PipelineRegister
|
||||||
|
@@ -25,66 +25,66 @@ entity OPDecoder is
|
|||||||
--@ Synchronous reset signal (**Active high**)
|
--@ Synchronous reset signal (**Active high**)
|
||||||
I_RST : in std_logic;
|
I_RST : in std_logic;
|
||||||
|
|
||||||
--@ @virtualbus Operation-Write @dir in Operation Write Interface
|
--@ @virtualbus Decoder-OP @dir in Operation Write Interface
|
||||||
--@ Indicates if the `OPCode` and `OPData` are valid. (**Active high**)
|
--@ AXI like valid; (**Synchronous**, **Active high**)
|
||||||
I_OP_Valid : in std_logic := '0';
|
I_OPDecoder_Valid : in std_logic := '0';
|
||||||
--@ Indicates if the decoder is ready to accept data. (**Active high**)
|
--@ AXI like ready; (**Synchronous**, **Active high**)
|
||||||
O_OP_Ready : out std_logic := '0';
|
O_OPDecoder_Ready : out std_logic := '0';
|
||||||
--@ Operation code for the sprite channel
|
--@ Operation code for the sprite channel
|
||||||
I_OP_Code : in std_logic_vector(3 downto 0) := (others => '0');
|
I_OPDecoder_Code : in std_logic_vector(3 downto 0) := (others => '0');
|
||||||
--@ Data to be used with the operation code.
|
--@ Operation data for the sprite channel
|
||||||
I_OP_Data : in std_logic_vector(G_OPCodeData_Width - 1 downto 0) := (others => '0');
|
I_OPDecoder_Data : in std_logic_vector(G_OPCodeData_Width - 1 downto 0) := (others => '0');
|
||||||
--@ @end
|
--@ @end
|
||||||
|
|
||||||
--@ @virtualbus Register-Write @dir out Bus to write to the register file
|
--@ @virtualbus Register-Write @dir out Bus to write to the register file
|
||||||
--@ Write enable for the sprite index register; (**Active high**)
|
--@ 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.
|
--@ 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**)
|
--@ 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.
|
--@ 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**)
|
--@ 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.
|
--@ 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**)
|
--@ 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.
|
--@ 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**)
|
--@ 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.
|
--@ Flag to write to the `IsVisible` flag.
|
||||||
O_IsVisible : out std_logic := '0';
|
O_RFile_Wr_IsVisible : out std_logic := '0';
|
||||||
--@ @end
|
--@ @end
|
||||||
|
|
||||||
--@ @virtualbus Register-Read @dir In Parallel read interface to the register file
|
--@ @virtualbus Register-Read @dir In Parallel read interface to the register file
|
||||||
--@ Indicates if the sprite is in the line visible.
|
--@ Indicates if the sprite is in the line visible.
|
||||||
I_IsVisible : in std_logic := '0';
|
I_RFile_IsVisible : in std_logic := '0';
|
||||||
--@ @end
|
--@ @end
|
||||||
|
|
||||||
--@ @virtualbus YHitCheck-Input-Interface @dir in YHitCheck Input Interface
|
--@ @virtualbus VSpritePipeline-OP @dir Out Vertical sprite pipeline operation interface
|
||||||
--@ Indicates if the pipeline is ready to accept data. **Active high**
|
--@ AXI like ready; (**Synchronous**, **Active high**)
|
||||||
I_YHitCheck_Ready : in std_logic := '0';
|
I_VSpritePipeline_Ready : in std_logic := '0';
|
||||||
--@ Indicates if the pipeline is valid. **Active high**
|
--@ AXI like valid; (**Synchronous**, **Active high**)
|
||||||
O_YHitCheck_Valid : out std_logic := '0';
|
O_VSpritePipeline_Valid : out std_logic := '0';
|
||||||
--@ The line to check if the sprite is in the line visible.
|
--@ The requested Y position (line).
|
||||||
O_YHitCheck_YToCheck : out std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0');
|
O_VSpritePipeline_YToCheck : out std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0');
|
||||||
--@ @end
|
--@ @end
|
||||||
|
|
||||||
--@ @virtualbus YHitCheck-Output-Interface @dir out YHitCheck Output Interface
|
--@ @virtualbus VSpritePipeline-Result @dir In Vertical sprite pipeline result interface
|
||||||
--@ Indicates if the pipeline is ready to deliver data. **Active high**
|
--@ AXI like ready; (**Synchronous**, **Active high**)
|
||||||
O_YHitCheck_Ready : out std_logic := '0';
|
O_VSpritePipeline_Ready : out std_logic := '0';
|
||||||
--@ Indicates if `O_IsVisible` is valid. **Active high**
|
--@ AXI like valid; (**Synchronous**, **Active high**)
|
||||||
I_YHitCheck_Valid : in std_logic := '0';
|
I_VSpritePipeline_Valid : in std_logic := '0';
|
||||||
--@ Indicates if the sprite is visible in the line.
|
--@ 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.
|
--@ 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
|
--@ @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**)
|
--@ AXI like valid; (**Synchronous**, **Active high**)
|
||||||
O_HSpritePipeline_Valid : out std_logic := '0';
|
O_HSpritePipeline_Valid : out std_logic := '0';
|
||||||
--@ AXI like ready; (**Synchronous**, **Active high**)
|
--@ AXI like ready; (**Synchronous**, **Active high**)
|
||||||
@@ -96,71 +96,73 @@ entity OPDecoder is
|
|||||||
end OPDecoder;
|
end OPDecoder;
|
||||||
|
|
||||||
architecture RTL of OPDecoder is
|
architecture RTL of OPDecoder is
|
||||||
signal C_OP_Ready : std_logic := '0';
|
--@ States type for the state machine
|
||||||
|
|
||||||
type T_State is (
|
type T_State is (
|
||||||
S_Ready,
|
S_Ready,
|
||||||
S_Dispatch_YHitCheck,
|
S_Dispatch_YHitCheck,
|
||||||
S_WaitResponse_YHitCheck,
|
S_WaitResponse_YHitCheck,
|
||||||
S_Dispatch_CalcPipeline
|
S_Dispatch_CalcPipeline
|
||||||
);
|
);
|
||||||
|
--@ Current state of the state machine
|
||||||
signal R_State : T_State := S_Ready;
|
signal R_State : T_State := S_Ready;
|
||||||
|
--@ Next state of the state machine
|
||||||
signal C_NextState : T_State := S_Ready;
|
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';
|
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');
|
signal R_OP_Data : std_logic_vector(G_OPCodeData_Width - 1 downto 0) := (others => '0');
|
||||||
begin
|
begin
|
||||||
O_OP_Ready <= C_OP_Ready;
|
P_OP_Data_Register : process (I_CLK)
|
||||||
|
|
||||||
P_RegisterNewLineReq : process (I_CLK)
|
|
||||||
begin
|
begin
|
||||||
if rising_edge(I_CLK) then
|
if rising_edge(I_CLK) then
|
||||||
if I_CE = '1' then
|
if I_RST = '1' then
|
||||||
if I_RST = '1' then
|
R_OP_Data <= (others => '0');
|
||||||
R_OP_Data <= (others => '0');
|
elsif I_CE = '1' then
|
||||||
elsif C_OP_Data_WE = '1' then
|
if C_OP_Data_WE = '1' then
|
||||||
R_OP_Data <= I_OP_Data;
|
R_OP_Data <= I_OPDecoder_Data;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
P_StateForwarding : process (I_CLK)
|
P_FSM_StateForwarding : process (I_CLK)
|
||||||
begin
|
begin
|
||||||
if rising_edge(I_CLK) then
|
if rising_edge(I_CLK) then
|
||||||
if I_CE = '1' then
|
if I_RST = '1' then
|
||||||
if I_RST = '1' then
|
R_State <= S_Ready;
|
||||||
R_State <= S_Ready;
|
elsif I_CE = '1' then
|
||||||
else
|
R_State <= C_NextState;
|
||||||
R_State <= C_NextState;
|
|
||||||
end if;
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
P_StateMachine : process (
|
P_FSM : process (
|
||||||
R_State, I_OP_Code, R_OP_Data, I_OP_Valid,
|
R_State, I_OPDecoder_Code, R_OP_Data, I_OPDecoder_Valid,
|
||||||
I_YHitCheck_Ready, I_YHitCheck_Valid, I_YHitCheck_IsVisible, I_YHitCheck_Offset,
|
I_VSpritePipeline_Ready, I_VSpritePipeline_Valid, I_VSpritePipeline_IsVisible, I_VSpritePipeline_Offset,
|
||||||
I_HSpritePipeline_Ready, I_OP_Data, I_IsVisible
|
I_HSpritePipeline_Ready, I_OPDecoder_Data, I_RFile_IsVisible
|
||||||
)
|
)
|
||||||
begin
|
begin
|
||||||
-- Default the next state to the current state
|
-- Default the next state to the current state
|
||||||
C_NextState <= R_State;
|
C_NextState <= R_State;
|
||||||
|
|
||||||
-- Default the output signals to prevent latches
|
-- Default the output signals to prevent latches
|
||||||
O_Register_Index_WE <= '0';
|
O_RFile_Wr_Index_WE <= '0';
|
||||||
O_Register_Index <= (others => '0');
|
O_RFile_Wr_Index <= (others => '0');
|
||||||
O_Register_X_We <= '0';
|
O_RFile_Wr_X_We <= '0';
|
||||||
O_Register_X <= (others => '0');
|
O_RFile_Wr_X <= (others => '0');
|
||||||
O_Register_Y_WE <= '0';
|
O_RFile_Wr_Y_WE <= '0';
|
||||||
O_Register_Y <= (others => '0');
|
O_RFile_Wr_Y <= (others => '0');
|
||||||
O_Register_Offset_WE <= '0';
|
O_RFile_Wr_Offset_WE <= '0';
|
||||||
O_Register_Offset <= (others => '0');
|
O_RFile_Wr_Offset <= (others => '0');
|
||||||
O_IsVisible_WE <= '0';
|
O_RFile_Wr_IsVisible_WE <= '0';
|
||||||
O_IsVisible <= '0';
|
O_RFile_Wr_IsVisible <= '0';
|
||||||
O_YHitCheck_Valid <= '0';
|
O_VSpritePipeline_Valid <= '0';
|
||||||
O_YHitCheck_Ready <= '0';
|
O_VSpritePipeline_Ready <= '0';
|
||||||
O_YHitCheck_YToCheck <= (others => '0');
|
O_VSpritePipeline_YToCheck <= (others => '0');
|
||||||
C_OP_Ready <= '0';
|
C_OP_Ready <= '0';
|
||||||
O_HSpritePipeline_Valid <= '0';
|
O_HSpritePipeline_Valid <= '0';
|
||||||
O_HSpritePipeline_X_Request <= (others => '0');
|
O_HSpritePipeline_X_Request <= (others => '0');
|
||||||
@@ -172,57 +174,57 @@ begin
|
|||||||
C_OP_Ready <= '1';
|
C_OP_Ready <= '1';
|
||||||
C_OP_Data_WE <= '1';
|
C_OP_Data_WE <= '1';
|
||||||
|
|
||||||
if I_OP_Valid = '1' then
|
if I_OPDecoder_Valid = '1' then
|
||||||
case I_OP_Code is
|
case I_OPDecoder_Code is
|
||||||
when K_OP_NOP =>
|
when K_OP_NOP =>
|
||||||
C_NextState <= S_Ready;
|
C_NextState <= S_Ready;
|
||||||
|
|
||||||
when K_OP_NEWLINE =>
|
when K_OP_NEWLINE =>
|
||||||
O_IsVisible_WE <= '0';
|
O_RFile_Wr_IsVisible_WE <= '0';
|
||||||
O_IsVisible <= '0';
|
O_RFile_Wr_IsVisible <= '0';
|
||||||
|
|
||||||
C_NextState <= S_Dispatch_YHitCheck;
|
C_NextState <= S_Dispatch_YHitCheck;
|
||||||
|
|
||||||
when K_OP_SET_ID =>
|
when K_OP_SET_ID =>
|
||||||
O_Register_Index_WE <= '1';
|
O_RFile_Wr_Index_WE <= '1';
|
||||||
O_Register_Index <= I_OP_Data(G_Index_Width - 1 downto 0);
|
O_RFile_Wr_Index <= I_OPDecoder_Data(G_Index_Width - 1 downto 0);
|
||||||
|
|
||||||
C_NextState <= S_Ready;
|
C_NextState <= S_Ready;
|
||||||
|
|
||||||
when K_OP_SET_X =>
|
when K_OP_SET_X =>
|
||||||
O_Register_X_We <= '1';
|
O_RFile_Wr_X_We <= '1';
|
||||||
O_Register_X <= I_OP_Data(G_X_Width - 1 downto 0);
|
O_RFile_Wr_X <= I_OPDecoder_Data(G_X_Width - 1 downto 0);
|
||||||
|
|
||||||
C_NextState <= S_Ready;
|
C_NextState <= S_Ready;
|
||||||
|
|
||||||
when K_OP_SET_Y =>
|
when K_OP_SET_Y =>
|
||||||
O_Register_Y_WE <= '1';
|
O_RFile_Wr_Y_WE <= '1';
|
||||||
O_Register_Y <= I_OP_Data(G_Y_Width - 1 downto 0);
|
O_RFile_Wr_Y <= I_OPDecoder_Data(G_Y_Width - 1 downto 0);
|
||||||
|
|
||||||
C_NextState <= S_Ready;
|
C_NextState <= S_Ready;
|
||||||
|
|
||||||
when K_OP_REQ_ROW_DATA =>
|
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;
|
C_NextState <= S_Dispatch_CalcPipeline;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
when K_OP_CLEAR_ALL =>
|
when K_OP_CLEAR_ALL =>
|
||||||
O_Register_Index_WE <= '1';
|
O_RFile_Wr_Index_WE <= '1';
|
||||||
O_Register_Index <= (others => '0');
|
O_RFile_Wr_Index <= (others => '0');
|
||||||
--
|
--
|
||||||
O_Register_X_We <= '1';
|
O_RFile_Wr_X_We <= '1';
|
||||||
O_Register_X <= (others => '0');
|
O_RFile_Wr_X <= (others => '0');
|
||||||
--
|
--
|
||||||
O_Register_Y_WE <= '1';
|
O_RFile_Wr_Y_WE <= '1';
|
||||||
O_Register_Y <= (others => '0');
|
O_RFile_Wr_Y <= (others => '0');
|
||||||
--
|
--
|
||||||
O_Register_Offset_WE <= '1';
|
O_RFile_Wr_Offset_WE <= '1';
|
||||||
O_Register_Offset <= (others => '0');
|
O_RFile_Wr_Offset <= (others => '0');
|
||||||
--
|
--
|
||||||
O_IsVisible_WE <= '1';
|
O_RFile_Wr_IsVisible_WE <= '1';
|
||||||
O_IsVisible <= '0';
|
O_RFile_Wr_IsVisible <= '0';
|
||||||
|
|
||||||
C_NextState <= S_Ready;
|
C_NextState <= S_Ready;
|
||||||
|
|
||||||
when others =>
|
when others =>
|
||||||
C_NextState <= S_Ready;
|
C_NextState <= S_Ready;
|
||||||
@@ -231,24 +233,24 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
|
|
||||||
when S_Dispatch_YHitCheck =>
|
when S_Dispatch_YHitCheck =>
|
||||||
O_YHitCheck_Valid <= '1';
|
O_VSpritePipeline_Valid <= '1';
|
||||||
O_YHitCheck_YToCheck <= R_OP_Data(G_Y_Width - 1 downto 0);
|
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;
|
C_NextState <= S_WaitResponse_YHitCheck;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
when S_WaitResponse_YHitCheck =>
|
when S_WaitResponse_YHitCheck =>
|
||||||
O_YHitCheck_Ready <= '1';
|
O_VSpritePipeline_Ready <= '1';
|
||||||
|
|
||||||
if I_YHitCheck_Valid = '1' then
|
if I_VSpritePipeline_Valid = '1' then
|
||||||
O_IsVisible_WE <= '1';
|
O_RFile_Wr_IsVisible_WE <= '1';
|
||||||
O_IsVisible <= I_YHitCheck_IsVisible;
|
O_RFile_Wr_IsVisible <= I_VSpritePipeline_IsVisible;
|
||||||
|
|
||||||
O_Register_Offset_WE <= '1';
|
O_RFile_Wr_Offset_WE <= '1';
|
||||||
O_Register_Offset <= I_YHitCheck_Offset;
|
O_RFile_Wr_Offset <= I_VSpritePipeline_Offset;
|
||||||
|
|
||||||
C_NextState <= S_Ready;
|
C_NextState <= S_Ready;
|
||||||
|
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
@@ -262,4 +264,5 @@ begin
|
|||||||
end case;
|
end case;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
|
O_OPDecoder_Ready <= C_OP_Ready;
|
||||||
end architecture;
|
end architecture;
|
||||||
|
@@ -16,45 +16,45 @@ entity RegisterFile is
|
|||||||
);
|
);
|
||||||
port (
|
port (
|
||||||
--@ Clock signal; (**Rising edge** triggered)
|
--@ Clock signal; (**Rising edge** triggered)
|
||||||
I_CLK : in std_logic;
|
I_CLK : in std_logic;
|
||||||
--@ Clock enable signal (**Active high**)
|
--@ Clock enable signal (**Active high**)
|
||||||
I_CE : in std_logic := '1';
|
I_CE : in std_logic := '1';
|
||||||
--@ Synchronous reset signal (**Active high**)
|
--@ 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**)
|
--@ 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.
|
--@ 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**)
|
--@ 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.
|
--@ 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**)
|
--@ 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.
|
--@ 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**)
|
--@ 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.
|
--@ 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**)
|
--@ 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.
|
--@ 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.
|
--@ 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.
|
--@ 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.
|
--@ 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.
|
--@ 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**)
|
--@ 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
|
||||||
);
|
);
|
||||||
end entity;
|
end entity;
|
||||||
@@ -83,24 +83,24 @@ begin
|
|||||||
R_Y <= (others => '0');
|
R_Y <= (others => '0');
|
||||||
R_IsVisible <= '0';
|
R_IsVisible <= '0';
|
||||||
elsif I_CE = '1' then
|
elsif I_CE = '1' then
|
||||||
if I_Index_WE = '1' then
|
if I_RFile_Wr_Index_WE = '1' then
|
||||||
R_Index <= I_Index;
|
R_Index <= I_RFile_Wr_Index;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
if I_Offset_WE = '1' then
|
if I_RFile_Wr_Offset_WE = '1' then
|
||||||
R_Offset <= I_Offset;
|
R_Offset <= I_RFile_Wr_Offset;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
if I_X_We = '1' then
|
if I_RFile_Wr_X_We = '1' then
|
||||||
R_X <= I_X;
|
R_X <= I_RFile_Wr_X;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
if I_Y_WE = '1' then
|
if I_RFile_Wr_Y_WE = '1' then
|
||||||
R_Y <= I_Y;
|
R_Y <= I_RFile_Wr_Y;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
if I_IsVisible_WE = '1' then
|
if I_RFile_Wr_IsVisible_WE = '1' then
|
||||||
R_IsVisible <= I_IsVisible;
|
R_IsVisible <= I_RFile_Wr_IsVisible;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
@@ -112,11 +112,11 @@ begin
|
|||||||
R_IsVisible
|
R_IsVisible
|
||||||
)
|
)
|
||||||
begin
|
begin
|
||||||
O_Index <= R_Index;
|
O_RFile_Index <= R_Index;
|
||||||
O_Offset <= R_Offset;
|
O_RFile_Offset <= R_Offset;
|
||||||
O_X <= R_X;
|
O_RFile_X <= R_X;
|
||||||
O_Y <= R_Y;
|
O_RFile_Y <= R_Y;
|
||||||
O_IsVisible <= R_IsVisible;
|
O_RFile_IsVisible <= R_IsVisible;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
end architecture;
|
end architecture;
|
||||||
|
@@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
NET I_CLK LOC = B8;
|
NET I_CLK LOC = B8;
|
||||||
NET I_CLK TNM_NET = CLOCK;
|
NET I_CLK TNM_NET = CLOCK;
|
||||||
TIMESPEC TS_CLOCK = PERIOD CLOCK 230 MHz HIGH 50 %;
|
TIMESPEC TS_CLOCK = PERIOD CLOCK 220 MHz HIGH 50 %;
|
@@ -8,116 +8,100 @@ entity SpriteChannel is
|
|||||||
--@ Data width of the operation data.
|
--@ Data width of the operation data.
|
||||||
G_OPCodeData_Width : integer := 10;
|
G_OPCodeData_Width : integer := 10;
|
||||||
--@ Width of the sprite index (Base address) register
|
--@ 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
|
--@ 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
|
--@ Width of the X position (Row) register
|
||||||
G_X_Width : integer := 10;
|
G_X_Width : integer := 10;
|
||||||
--@ Width of the Y position (Line) register
|
--@ Width of the Y position (Line) register
|
||||||
G_Y_Width : integer := 10;
|
G_Y_Width : integer := 10;
|
||||||
--@ The height of the sprite in pixels
|
--@ The height of the sprite in pixels
|
||||||
G_Sprite_Height : integer := 16;
|
G_Sprite_Height : integer := 16;
|
||||||
--@ The width of the sprite in pixels
|
--@ The width of the sprite in pixels
|
||||||
G_Sprite_Width : integer := 16
|
G_Sprite_Width : integer := 16
|
||||||
);
|
);
|
||||||
port (
|
port (
|
||||||
--@ Clock signal; **Rising edge** triggered
|
--@ Clock signal; **Rising edge** triggered
|
||||||
I_CLK : in std_logic;
|
I_CLK : in std_logic;
|
||||||
--@ Clock Enable signal
|
--@ Clock Enable signal
|
||||||
I_CE : in std_logic;
|
I_CE : in std_logic;
|
||||||
--@ Synchronous reset signal
|
--@ Synchronous reset signal
|
||||||
I_RST : in std_logic;
|
I_RST : in std_logic;
|
||||||
|
|
||||||
--@ @virtualbus Operation-Write @dir in Operation Write Interface
|
--@ @virtualbus Operation-Write @dir in Operation Write Interface
|
||||||
--@ Indicates if the `OPCode` and `OPData` are valid. (**Active high**)
|
--@ 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**)
|
--@ 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
|
--@ 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.
|
--@ 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
|
--@ @end
|
||||||
|
|
||||||
--@ @virtualbus Pixel-Data @dir Out Pixel data output bus
|
--@ @virtualbus Pixel-Data @dir Out Pixel data output bus
|
||||||
--@ AXI like valid; (**Synchronous**, **Active high**)
|
--@ AXI like valid; (**Synchronous**, **Active high**)
|
||||||
O_Pixel_Valid : out std_logic;
|
O_Pixel_Valid : out std_logic;
|
||||||
--@ AXI like ready; (**Synchronous**, **Active high**)
|
--@ AXI like ready; (**Synchronous**, **Active high**)
|
||||||
I_Pixel_Ready : in std_logic;
|
I_Pixel_Ready : in std_logic;
|
||||||
--@ Pixel data
|
--@ Pixel data
|
||||||
O_Pixel_Data : out std_logic_vector(7 downto 0)
|
O_Pixel_Data : out std_logic_vector(7 downto 0)
|
||||||
--@ @end
|
--@ @end
|
||||||
|
|
||||||
);
|
);
|
||||||
end entity;
|
end entity;
|
||||||
|
|
||||||
architecture RTL of SpriteChannel is
|
architecture RTL of SpriteChannel is
|
||||||
signal R_Index : std_logic_vector(G_Index_Width - 1 downto 0) := (others => '0');
|
-- Register file signals --
|
||||||
signal R_Offset : std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0');
|
signal I_RFile_Wr_Index_WE : std_logic := '0';
|
||||||
signal R_X : std_logic_vector(G_X_Width - 1 downto 0) := (others => '0');
|
signal I_RFile_Wr_Index : std_logic_vector(G_Index_Width - 1 downto 0) := (others => '0');
|
||||||
signal R_Y : std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0');
|
signal I_RFile_Wr_Offset_WE : std_logic := '0';
|
||||||
signal R_IsVisible : 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';
|
-- Vertical sprite pipeline signals --
|
||||||
signal IO_P0_Address_Ready : std_logic := '0';
|
signal O_VSpritePipeline_OP_Ready : std_logic := '0';
|
||||||
signal OI_P0_Address : std_logic_vector(G_Index_Width + G_Offset_Width - 1 downto 0) := (others => '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';
|
-- Horizontal sprite pipeline signals --
|
||||||
signal OI_P0_Data_Ready : std_logic := '0';
|
signal I_HSpritePipeline_OP_Valid : std_logic;
|
||||||
signal IO_P0_Data : std_logic_vector(7 downto 0) := (others => '0');
|
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
|
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(
|
generic map(
|
||||||
G_OPCodeData_Width => G_OPCodeData_Width,
|
G_OPCodeData_Width => G_OPCodeData_Width,
|
||||||
G_Index_Width => G_Index_Width,
|
G_Index_Width => G_Index_Width,
|
||||||
@@ -126,107 +110,110 @@ begin
|
|||||||
G_Y_Width => G_Y_Width
|
G_Y_Width => G_Y_Width
|
||||||
)
|
)
|
||||||
port map(
|
port map(
|
||||||
I_CLK => I_CLK,
|
I_CLK => I_CLK,
|
||||||
I_CE => I_CE,
|
I_CE => I_CE,
|
||||||
I_RST => I_RST,
|
I_RST => I_RST,
|
||||||
I_OP_Valid => I_OP_Valid,
|
I_OPDecoder_Valid => I_OP_Valid,
|
||||||
O_OP_Ready => O_OP_Ready,
|
O_OPDecoder_Ready => O_OP_Ready,
|
||||||
I_OP_Code => I_OP_Code,
|
I_OPDecoder_Code => I_OP_Code,
|
||||||
I_OP_Data => I_OP_Data,
|
I_OPDecoder_Data => I_OP_Data,
|
||||||
O_Register_Index_WE => OI_Register_Index_WE,
|
O_RFile_Wr_Index_WE => I_RFile_Wr_Index_WE,
|
||||||
O_Register_Index => OI_Register_Index,
|
O_RFile_Wr_Index => I_RFile_Wr_Index,
|
||||||
O_Register_Offset_WE => OI_Register_Offset_WE,
|
O_RFile_Wr_Offset_WE => I_RFile_Wr_Offset_WE,
|
||||||
O_Register_Offset => OI_Register_Offset,
|
O_RFile_Wr_Offset => I_RFile_Wr_Offset,
|
||||||
O_Register_X_We => OI_Register_X_We,
|
O_RFile_Wr_X_We => I_RFile_Wr_X_We,
|
||||||
O_Register_X => OI_Register_X,
|
O_RFile_Wr_X => I_RFile_Wr_X,
|
||||||
O_Register_Y_WE => OI_Register_Y_WE,
|
O_RFile_Wr_Y_WE => I_RFile_Wr_Y_WE,
|
||||||
O_Register_Y => OI_Register_Y,
|
O_RFile_Wr_Y => I_RFile_Wr_Y,
|
||||||
O_IsVisible_WE => OI_IsVisible_WE,
|
O_RFile_Wr_IsVisible_WE => I_RFile_Wr_IsVisible_WE,
|
||||||
O_IsVisible => OI_IsVisible,
|
O_RFile_Wr_IsVisible => I_RFile_Wr_IsVisible,
|
||||||
|
I_RFile_IsVisible => O_RFile_IsVisible,
|
||||||
I_IsVisible => R_IsVisible,
|
I_VSpritePipeline_Ready => O_VSpritePipeline_OP_Ready,
|
||||||
|
O_VSpritePipeline_Valid => I_VSpritePipeline_OP_Valid,
|
||||||
I_YHitCheck_Ready => I_YHitCheck_Ready,
|
O_VSpritePipeline_YToCheck => I_VSpritePipeline_OP_Y_Request,
|
||||||
O_YHitCheck_Valid => O_YHitCheck_Valid,
|
O_VSpritePipeline_Ready => I_VSpritePipeline_Ready,
|
||||||
O_YHitCheck_YToCheck => O_YHitCheck_YToCheck,
|
I_VSpritePipeline_Valid => O_VSpritePipeline_Valid,
|
||||||
O_YHitCheck_Ready => O_YHitCheck_Ready,
|
I_VSpritePipeline_IsVisible => O_VSpritePipeline_IsVisible,
|
||||||
I_YHitCheck_Valid => I_YHitCheck_Valid,
|
I_VSpritePipeline_Offset => O_VSpritePipeline_Offset,
|
||||||
I_YHitCheck_IsVisible => I_YHitCheck_IsVisible,
|
O_HSpritePipeline_Valid => I_HSpritePipeline_OP_Valid,
|
||||||
I_YHitCheck_Offset => I_YHitCheck_Offset,
|
I_HSpritePipeline_Ready => O_HSpritePipeline_OP_Ready,
|
||||||
|
O_HSpritePipeline_X_Request => I_HSpritePipeline_OP_X_Request
|
||||||
O_HSpritePipeline_Valid => OI_CalcPipeline_Valid,
|
|
||||||
I_HSpritePipeline_Ready => IO_CalcPipeline_Ready,
|
|
||||||
O_HSpritePipeline_X_Request => OI_CalcPipeline_X_Request
|
|
||||||
);
|
);
|
||||||
|
|
||||||
i_YHitCheck : entity work.VerticalSpritePipeline
|
INST_RFile : entity work.RegisterFile
|
||||||
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
|
|
||||||
generic map(
|
generic map(
|
||||||
G_Index_Width => G_Index_Width,
|
G_Index_Width => G_Index_Width,
|
||||||
G_Offset_Width => G_Offset_Width,
|
G_Offset_Width => G_Offset_Width,
|
||||||
G_X_Width => G_X_Width,
|
G_X_Width => G_X_Width,
|
||||||
G_Rom_Width => 8,
|
G_Y_Width => G_Y_Width
|
||||||
G_Pixel_Width => 8
|
|
||||||
)
|
)
|
||||||
port map(
|
port map(
|
||||||
I_CLK => I_CLK,
|
I_CLK => I_CLK,
|
||||||
I_CE => I_CE,
|
I_CE => I_CE,
|
||||||
I_RST => I_RST,
|
I_RST => I_RST,
|
||||||
I_OP_Valid => OI_CalcPipeline_Valid,
|
I_RFile_Wr_Index_WE => I_RFile_Wr_Index_WE,
|
||||||
O_OP_Ready => IO_CalcPipeline_Ready,
|
I_RFile_Wr_Index => I_RFile_Wr_Index,
|
||||||
I_OP_X_Request => OI_CalcPipeline_X_Request,
|
I_RFile_Wr_Offset_WE => I_RFile_Wr_Offset_WE,
|
||||||
I_OP_Index => R_Index,
|
I_RFile_Wr_Offset => I_RFile_Wr_Offset,
|
||||||
I_OP_Offset => R_Offset,
|
I_RFile_Wr_X_We => I_RFile_Wr_X_We,
|
||||||
I_OP_X_Sprite => R_X,
|
I_RFile_Wr_X => I_RFile_Wr_X,
|
||||||
O_Rom_Valid => OI_P0_Address_Valid,
|
I_RFile_Wr_Y_WE => I_RFile_Wr_Y_WE,
|
||||||
I_Rom_Ready => IO_P0_Address_Ready,
|
I_RFile_Wr_Y => I_RFile_Wr_Y,
|
||||||
O_Rom_Address => OI_P0_Address,
|
I_RFile_Wr_IsVisible_WE => I_RFile_Wr_IsVisible_WE,
|
||||||
I_Rom_Valid => IO_P0_Data_Valid,
|
I_RFile_Wr_IsVisible => I_RFile_Wr_IsVisible,
|
||||||
O_Rom_Ready => OI_P0_Data_Ready,
|
O_RFile_Index => O_RFile_Index,
|
||||||
I_Rom_Data => IO_P0_Data,
|
O_RFile_Offset => O_RFile_Offset,
|
||||||
O_Pixel_Valid => O_Pixel_Valid,
|
O_RFile_X => O_RFile_X,
|
||||||
I_Pixel_Ready => I_Pixel_Ready,
|
O_RFile_Y => O_RFile_Y,
|
||||||
O_Pixel_Data => O_Pixel_Data
|
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;
|
end architecture RTL;
|
||||||
|
@@ -9,17 +9,17 @@ end entity OPDecoder_tb;
|
|||||||
|
|
||||||
architecture bench of OPDecoder_tb is
|
architecture bench of OPDecoder_tb is
|
||||||
-- Clock period
|
-- Clock period
|
||||||
constant K_CLKPeriod : time := 10 ns;
|
constant K_CLKPeriod : time := 10 ns;
|
||||||
-- Generics
|
-- Generics
|
||||||
constant G_OPCodeData_Width : integer := 10;
|
constant G_OPCodeData_Width : integer := 10;
|
||||||
constant G_ROM_DataWidth : integer := 16;
|
constant G_ROM_DataWidth : integer := 16;
|
||||||
constant G_Index_Width : integer := 6;
|
constant G_Index_Width : integer := 6;
|
||||||
constant G_Offset_Width : integer := 4;
|
constant G_Offset_Width : integer := 4;
|
||||||
constant G_LineData_Width : integer := 16;
|
constant G_LineData_Width : integer := 16;
|
||||||
constant G_X_Width : integer := 10;
|
constant G_X_Width : integer := 10;
|
||||||
constant G_Y_Width : integer := 10;
|
constant G_Y_Width : integer := 10;
|
||||||
constant G_Sprite_Height : integer := 16;
|
constant G_Sprite_Height : integer := 16;
|
||||||
constant G_PipelineStages : integer := 2;
|
constant G_PipelineStages : integer := 2;
|
||||||
|
|
||||||
-- Ports
|
-- Ports
|
||||||
signal I_CLK : std_logic;
|
signal I_CLK : std_logic;
|
||||||
@@ -57,9 +57,9 @@ architecture bench of OPDecoder_tb is
|
|||||||
signal I_CalcPipeline_Ready : std_logic := '0';
|
signal I_CalcPipeline_Ready : std_logic := '0';
|
||||||
signal O_CalcPipeline_X : std_logic_vector(G_X_Width - 1 downto 0) := (others => '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
|
begin
|
||||||
|
|
||||||
ClockProc : process
|
ClockProc : process
|
||||||
@@ -90,29 +90,29 @@ begin
|
|||||||
I_CLK => I_CLK,
|
I_CLK => I_CLK,
|
||||||
I_CE => I_CE,
|
I_CE => I_CE,
|
||||||
I_RST => I_RST,
|
I_RST => I_RST,
|
||||||
I_OP_Valid => I_OP_Valid,
|
I_OPDecoder_Valid => I_OP_Valid,
|
||||||
O_OP_Ready => O_OP_Ready,
|
O_OPDecoder_Ready => O_OP_Ready,
|
||||||
I_OP_Code => I_OP_Code,
|
I_OPDecoder_Code => I_OP_Code,
|
||||||
I_OP_Data => I_OP_Data,
|
I_OPDecoder_Data => I_OP_Data,
|
||||||
O_Register_Index_WE => O_Register_Index_WE,
|
O_RFile_Wr_Index_WE => O_Register_Index_WE,
|
||||||
O_Register_Index => O_Register_Index,
|
O_RFile_Wr_Index => O_Register_Index,
|
||||||
O_Register_Offset_WE => O_Register_Offset_WE,
|
O_RFile_Wr_Offset_WE => O_Register_Offset_WE,
|
||||||
O_Register_Offset => O_Register_Offset,
|
O_RFile_Wr_Offset => O_Register_Offset,
|
||||||
O_Register_X_We => O_Register_X_We,
|
O_RFile_Wr_X_We => O_Register_X_We,
|
||||||
O_Register_X => O_Register_X,
|
O_RFile_Wr_X => O_Register_X,
|
||||||
O_Register_Y_WE => O_Register_Y_WE,
|
O_RFile_Wr_Y_WE => O_Register_Y_WE,
|
||||||
O_Register_Y => O_Register_Y,
|
O_RFile_Wr_Y => O_Register_Y,
|
||||||
O_Register_CachedLineData_WE => O_Register_CachedLineData_WE,
|
O_Register_CachedLineData_WE => O_Register_CachedLineData_WE,
|
||||||
O_Register_CachedLineData => O_Register_CachedLineData,
|
O_Register_CachedLineData => O_Register_CachedLineData,
|
||||||
O_Register_CacheValid_WE => O_Register_CacheValid_WE,
|
O_Register_CacheValid_WE => O_Register_CacheValid_WE,
|
||||||
O_Register_CacheValid => O_Register_CacheValid,
|
O_Register_CacheValid => O_Register_CacheValid,
|
||||||
I_YHitCheck_Ready => I_YHitCheck_Ready,
|
I_VSpritePipeline_Ready => I_YHitCheck_Ready,
|
||||||
O_YHitCheck_Valid => O_YHitCheck_Valid,
|
O_VSpritePipeline_Valid => O_YHitCheck_Valid,
|
||||||
O_YHitCheck_YToCheck => O_YHitCheck_YToCheck,
|
O_VSpritePipeline_YToCheck => O_YHitCheck_YToCheck,
|
||||||
O_YHitCheck_Ready => O_YHitCheck_Ready,
|
O_VSpritePipeline_Ready => O_YHitCheck_Ready,
|
||||||
I_YHitCheck_Valid => I_YHitCheck_Valid,
|
I_VSpritePipeline_Valid => I_YHitCheck_Valid,
|
||||||
I_YHitCheck_IsVisible => I_YHitCheck_IsVisible,
|
I_VSpritePipeline_IsVisible => I_YHitCheck_IsVisible,
|
||||||
I_YHitCheck_Offset => I_YHitCheck_Offset,
|
I_VSpritePipeline_Offset => I_YHitCheck_Offset,
|
||||||
O_Rom_Valid => O_Rom_Valid,
|
O_Rom_Valid => O_Rom_Valid,
|
||||||
I_Rom_Ready => I_Rom_Ready,
|
I_Rom_Ready => I_Rom_Ready,
|
||||||
I_Rom_Valid => I_Rom_Valid,
|
I_Rom_Valid => I_Rom_Valid,
|
||||||
@@ -133,16 +133,16 @@ begin
|
|||||||
G_PipelineStages => G_PipelineStages
|
G_PipelineStages => G_PipelineStages
|
||||||
)
|
)
|
||||||
port map(
|
port map(
|
||||||
I_CLK => I_CLK,
|
I_CLK => I_CLK,
|
||||||
I_CE => I_CE,
|
I_CE => I_CE,
|
||||||
O_Ready => I_YHitCheck_Ready,
|
O_VSpritePipeline_OP_Ready => I_YHitCheck_Ready,
|
||||||
I_Valid => O_YHitCheck_Valid,
|
I_VSpritePipeline_OP_Valid => O_YHitCheck_Valid,
|
||||||
I_YToCheck => O_YHitCheck_YToCheck,
|
I_VSpritePipeline_OP_Y_Request => O_YHitCheck_YToCheck,
|
||||||
I_Y => "0000000000",
|
I_VSpritePipeline_OP_Y_Sprite => "0000000000",
|
||||||
I_Ready => O_YHitCheck_Ready,
|
I_VSpritePipeline_Ready => O_YHitCheck_Ready,
|
||||||
O_Valid => I_YHitCheck_Valid,
|
O_VSpritePipeline_Valid => I_YHitCheck_Valid,
|
||||||
O_IsVisible => I_YHitCheck_IsVisible,
|
O_VSpritePipeline_IsVisible => I_YHitCheck_IsVisible,
|
||||||
O_Offset => I_YHitCheck_Offset
|
O_VSpritePipeline_Offset => I_YHitCheck_Offset
|
||||||
);
|
);
|
||||||
|
|
||||||
StimulusProc : process
|
StimulusProc : process
|
||||||
|
@@ -9,21 +9,21 @@ end;
|
|||||||
|
|
||||||
architecture bench of YHitCheck_tb is
|
architecture bench of YHitCheck_tb is
|
||||||
-- Clock period
|
-- Clock period
|
||||||
constant K_CLKPeriod : time := 10 ns;
|
constant K_CLKPeriod : time := 10 ns;
|
||||||
-- Generics
|
-- Generics
|
||||||
constant G_YWidth : integer := 10;
|
constant G_YWidth : integer := 10;
|
||||||
constant G_SpriteHeight : integer := 16;
|
constant G_SpriteHeight : integer := 16;
|
||||||
-- Ports
|
-- Ports
|
||||||
signal I_CLK : std_logic := '0';
|
signal I_CLK : std_logic := '0';
|
||||||
signal I_CE : std_logic;
|
signal I_CE : std_logic;
|
||||||
signal O_Ready : std_logic;
|
signal O_Ready : std_logic;
|
||||||
signal I_Valid : std_logic;
|
signal I_Valid : std_logic;
|
||||||
signal I_YToCheck : std_logic_vector(G_YWidth - 1 downto 0);
|
signal I_YToCheck : std_logic_vector(G_YWidth - 1 downto 0);
|
||||||
signal I_Y : 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 I_Ready : std_logic;
|
||||||
signal O_Valid : std_logic;
|
signal O_Valid : std_logic;
|
||||||
signal O_IsVisible : std_logic;
|
signal O_IsVisible : std_logic;
|
||||||
signal O_Offset : std_logic_vector(7 downto 0);
|
signal O_Offset : std_logic_vector(7 downto 0);
|
||||||
|
|
||||||
type T_TestData is record
|
type T_TestData is record
|
||||||
YToCheck : integer;
|
YToCheck : integer;
|
||||||
@@ -86,16 +86,16 @@ begin
|
|||||||
G_Sprite_Height => G_SpriteHeight
|
G_Sprite_Height => G_SpriteHeight
|
||||||
)
|
)
|
||||||
port map(
|
port map(
|
||||||
I_CLK => I_CLK,
|
I_CLK => I_CLK,
|
||||||
I_CE => I_CE,
|
I_CE => I_CE,
|
||||||
O_Ready => O_Ready,
|
O_VSpritePipeline_OP_Ready => O_Ready,
|
||||||
I_Valid => I_Valid,
|
I_VSpritePipeline_OP_Valid => I_Valid,
|
||||||
I_YToCheck => I_YToCheck,
|
I_VSpritePipeline_OP_Y_Request => I_YToCheck,
|
||||||
I_Y => I_Y,
|
I_VSpritePipeline_OP_Y_Sprite => I_Y,
|
||||||
I_Ready => I_Ready,
|
I_VSpritePipeline_Ready => I_Ready,
|
||||||
O_Valid => O_Valid,
|
O_VSpritePipeline_Valid => O_Valid,
|
||||||
O_IsVisible => O_IsVisible,
|
O_VSpritePipeline_IsVisible => O_IsVisible,
|
||||||
O_Offset => O_Offset
|
O_VSpritePipeline_Offset => O_Offset
|
||||||
);
|
);
|
||||||
|
|
||||||
StimulusProc : process
|
StimulusProc : process
|
||||||
|
Reference in New Issue
Block a user