This commit is contained in:
2025-04-22 15:23:15 +00:00
parent 7888d608ae
commit 73a436eb40
14 changed files with 1038 additions and 415 deletions

1
.gitignore vendored
View File

@@ -1,2 +1 @@
.locale/ .locale/
build/

2
build/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
working/
reports/

24
build/LICENSE.md Normal file
View 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
View 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
View 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
View 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
## ## ## ## ## ## ## ##
# ---------------------

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 %;

View File

@@ -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;

View File

@@ -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

View File

@@ -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