Initial commit
This commit is contained in:
commit
0d1b73e3e0
20
.gitignore
vendored
Normal file
20
.gitignore
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
.qsys_edit/
|
||||
c5_pin_model_dump.txt
|
||||
db/
|
||||
incremental_db/
|
||||
*.bak
|
||||
niosII.sopcinfo
|
||||
niosII/
|
||||
output_files/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.assembler
|
||||
.fitter
|
||||
.map
|
||||
.sta
|
||||
*.log
|
||||
*.o
|
||||
*.oo
|
||||
*.swp
|
||||
*.elf
|
||||
|
199
Makefile
Normal file
199
Makefile
Normal file
@ -0,0 +1,199 @@
|
||||
# Check for the required nios2-download command
|
||||
# The command is only available in nios2_command_shell
|
||||
ifeq (, $(shell which nios2-download))
|
||||
$(error "This makefile must be executed within the nios2_command_shell")
|
||||
endif
|
||||
|
||||
uname = $(shell uname -r)
|
||||
ifneq (,$(findstring Microsoft,${uname}))
|
||||
exe_suffix=.exe
|
||||
endif
|
||||
|
||||
# Programm pathes
|
||||
quartus_root ?= ${QUARTUS_ROOTDIR}
|
||||
intel_root ?= $(quartus_root)/..
|
||||
sopc_root = $(quartus_root)/sopc_builder
|
||||
|
||||
# Tools
|
||||
qsys_generate = $(sopc_root)/bin/qsys-generate$(exe_suffix)
|
||||
niosii_bsp = $(intel_root)/nios2eds/sdk2/bin/nios2-bsp
|
||||
quartus_map = quartus_map$(exe_suffix)
|
||||
quartus_fit = quartus_fit$(exe_suffix)
|
||||
quartus_asm = quartus_asm$(exe_suffix)
|
||||
quartus_sta = quartus_sta$(exe_suffix)
|
||||
nios2_bsp_generate_files = nios2-bsp-generate-files$(exe_suffix)
|
||||
quartus_pgm = quartus_pgm$(exe_suffix)
|
||||
nios2_download = nios2-download$(exe_suffix)
|
||||
nios2_terminal = nios2-terminal$(exe_suffix)
|
||||
|
||||
# Directories
|
||||
niosii_dir = niosII
|
||||
bsp_dir = software/signal_processing_bsp
|
||||
app_dir = software/signal_processing
|
||||
hw_test_dir = tests/hardware
|
||||
sw_test_dir = tests/software
|
||||
|
||||
# Settings
|
||||
quartus_project = signal_processing
|
||||
signal_processing_qsf = signal_processing.qsf
|
||||
|
||||
# Sources
|
||||
niosii_qsys = niosII.qsys
|
||||
|
||||
# Targets
|
||||
niosii_qip = $(niosii_dir)/synthesis/niosII.qip
|
||||
niosii_info = niosII.sopcinfo
|
||||
|
||||
bsp_settings = $(bsp_dir)/settings.bsp
|
||||
bsp_makefile = $(bsp_dir)/Makefile
|
||||
|
||||
# VHDL source files
|
||||
hdl_src += \
|
||||
hardware/system/sync_ff.vhd \
|
||||
hardware/system/sync_rst.vhd \
|
||||
hardware/system/pll/pll_main.vhd \
|
||||
hardware/system/reg32.vhd \
|
||||
hardware/system/avalon_slave_transitions.vhd \
|
||||
hardware/system/avalon_slave.vhd \
|
||||
hardware/system/data_sink_mux.vhd \
|
||||
hardware/system/fifo.vhd \
|
||||
hardware/system/data_source_mux.vhd \
|
||||
hardware/system/data_channel_control.vhd \
|
||||
hardware/system/data_channel.vhd \
|
||||
hardware/system/hardware_timestamp.vhd \
|
||||
hardware/system/task.vhd \
|
||||
hardware/system/float.vhd \
|
||||
hardware/system/hardware_task_control.vhd \
|
||||
hardware/system/hardware_task.vhd \
|
||||
hardware/system/float_add.vhd \
|
||||
hardware/signal_processing/add.vhd \
|
||||
hardware/system/task_add.vhd \
|
||||
hardware/signal_processing/rand.vhd \
|
||||
hardware/system/task_rand.vhd \
|
||||
hardware/system/cordic_pkg.vhd \
|
||||
hardware/system/cordic.vhd \
|
||||
hardware/system/fixed_sine.vhd \
|
||||
hardware/system/float_sine.vhd \
|
||||
hardware/signal_processing/sine.vhd \
|
||||
hardware/system/task_sine.vhd \
|
||||
hardware/system/Butterfly.v \
|
||||
hardware/system/DelayBuffer.v \
|
||||
hardware/system/FFT1024_32B.v \
|
||||
hardware/system/Multiply.v \
|
||||
hardware/system/SdfUnit2.v \
|
||||
hardware/system/SdfUnit.v \
|
||||
hardware/system/Twiddle1024_32B.v \
|
||||
hardware/system/squareRoot_pipe.vhd \
|
||||
hardware/system/fft_magnitude_calc.vhd \
|
||||
hardware/signal_processing/fft.vhd \
|
||||
hardware/system/task_fft.vhd \
|
||||
hardware/signal_processing/crc.vhd \
|
||||
hardware/system/task_crc.vhd \
|
||||
hardware/signal_processing/signal_processing.vhd \
|
||||
|
||||
#
|
||||
clean_items += \
|
||||
$(niosii_dir) \
|
||||
$(niosii_info) \
|
||||
.map \
|
||||
.fitter \
|
||||
.assembler \
|
||||
.sta \
|
||||
.qsys_edit/ \
|
||||
db/ \
|
||||
incremental_db/ \
|
||||
output_files/ \
|
||||
|
||||
.PHONY: all \
|
||||
niosII \
|
||||
fpga \
|
||||
program \
|
||||
clean \
|
||||
app \
|
||||
download \
|
||||
run \
|
||||
tests \
|
||||
|
||||
all: run
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Create the NiosII system from the description file
|
||||
niosII: $(niosii_info)
|
||||
|
||||
# Create the NiosII sources from the description file
|
||||
$(niosii_qip): $(niosii_qsys)
|
||||
@echo Generating the NiosII system from $< ...
|
||||
@$(qsys_generate) -syn=VHDL $<
|
||||
|
||||
# The NiosII system information file is created in parallel to the .qip file.
|
||||
$(niosii_info): $(niosii_qip)
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Quartus FPGA toolchain contains the mapper, fitter, assembler and static
|
||||
# timing analysis (sta).
|
||||
#
|
||||
fpga: .sta
|
||||
|
||||
# Anaylze and synthesis of the QuartusII project
|
||||
.map: $(hdl_src) $(niosii_info) $(signal_processing_qsf)
|
||||
@rm -f $@
|
||||
@$(quartus_map) --read_settings_files=on --write_settings_files=off $(quartus_project) -c $(quartus_project) && date > $@
|
||||
|
||||
# Run the quartus fitter on the project
|
||||
.fitter: .map $(sdc_src) $(signal_processing_qsf)
|
||||
@rm -f $@
|
||||
@$(quartus_fit) --read_settings_files=on --write_settings_files=off $(quartus_project) -c $(quartus_project) && date > $@
|
||||
|
||||
.assembler: .fitter
|
||||
@rm -f $@
|
||||
@$(quartus_asm) --read_settings_files=off --write_settings_files=off $(quartus_project) -c $(quartus_project)&& date > $@
|
||||
|
||||
.sta: .assembler
|
||||
@rm -f $@
|
||||
@$(quartus_sta) $(quartus_project) -c $(quartus_project) && date > $@
|
||||
|
||||
output_files/signal_processing_time_limited.sof: .sta
|
||||
|
||||
# Create the BSP from the sopc description
|
||||
bsp: ${bsp_makefile}
|
||||
|
||||
$(bsp_settings): $(niosii_info)
|
||||
@echo Generating the NiosII BSP from $< ...
|
||||
@$(niosii_bsp) hal $(bsp_dir) $<
|
||||
|
||||
$(bsp_makefile): $(bsp_settings)
|
||||
@$(nios2_bsp_generate_files) --settings software/signal_processing_bsp/settings.bsp --bsp-dir software/signal_processing_bsp/
|
||||
|
||||
app: $(bsp_makefile)
|
||||
${MAKE} -C $(app_dir)
|
||||
|
||||
# Programme the FPGA design
|
||||
program: output_files/signal_processing_time_limited.sof
|
||||
@$(quartus_pgm) signal_processing.cdf
|
||||
|
||||
# Programme the NiosII software design
|
||||
download: app
|
||||
@$(nios2-download) $(app_dir)/signal_processing.elf -g
|
||||
|
||||
# Programme the NiosII software design
|
||||
run: fpga download
|
||||
@$(nios2-terminal)
|
||||
|
||||
sw_tests:
|
||||
@${MAKE} -C tests/software
|
||||
|
||||
hw_tests:
|
||||
@${MAKE} -C tests/hardware
|
||||
|
||||
device_tests:
|
||||
@${MAKE} -C tests/device
|
||||
|
||||
tests: sw_tests hw_tests device_tests
|
||||
|
||||
clean:
|
||||
@rm -rf $(clean_items)
|
||||
@${MAKE} -C ${hw_test_dir} clean
|
||||
@${MAKE} -C ${sw_test_dir} clean
|
||||
@${MAKE} -C ${app_dir} clean
|
||||
@${MAKE} -C ${bsp_dir} clean
|
||||
|
195
data_channel_hw.tcl
Normal file
195
data_channel_hw.tcl
Normal file
@ -0,0 +1,195 @@
|
||||
# TCL File Generated by Component Editor 21.1
|
||||
# Fri Sep 09 13:42:23 CEST 2022
|
||||
# DO NOT MODIFY
|
||||
|
||||
|
||||
#
|
||||
# data_channel "data_channel" v1.0
|
||||
# Johannes Kutning 2022.09.09.13:42:23
|
||||
# A data channel for signal data transport
|
||||
#
|
||||
|
||||
#
|
||||
# request TCL package from ACDS 16.1
|
||||
#
|
||||
package require -exact qsys 16.1
|
||||
|
||||
|
||||
#
|
||||
# module data_channel
|
||||
#
|
||||
set_module_property DESCRIPTION "A data channel for signal data transport"
|
||||
set_module_property NAME data_channel
|
||||
set_module_property VERSION 1.0
|
||||
set_module_property INTERNAL false
|
||||
set_module_property OPAQUE_ADDRESS_MAP true
|
||||
set_module_property GROUP signal_processing
|
||||
set_module_property AUTHOR "Johannes Kutning"
|
||||
set_module_property DISPLAY_NAME data_channel
|
||||
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
|
||||
set_module_property EDITABLE true
|
||||
set_module_property REPORT_TO_TALKBACK false
|
||||
set_module_property ALLOW_GREYBOX_GENERATION false
|
||||
set_module_property REPORT_HIERARCHY false
|
||||
|
||||
|
||||
#
|
||||
# file sets
|
||||
#
|
||||
add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" ""
|
||||
set_fileset_property QUARTUS_SYNTH TOP_LEVEL data_channel
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
|
||||
set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
|
||||
add_fileset_file data_channel.vhd VHDL PATH hardware/system/data_channel.vhd TOP_LEVEL_FILE
|
||||
|
||||
|
||||
#
|
||||
# parameters
|
||||
#
|
||||
add_parameter DEPTH POSITIVE 1024
|
||||
set_parameter_property DEPTH DEFAULT_VALUE 1024
|
||||
set_parameter_property DEPTH DISPLAY_NAME DEPTH
|
||||
set_parameter_property DEPTH TYPE POSITIVE
|
||||
set_parameter_property DEPTH UNITS None
|
||||
set_parameter_property DEPTH ALLOWED_RANGES 1:2147483647
|
||||
set_parameter_property DEPTH HDL_PARAMETER true
|
||||
|
||||
|
||||
#
|
||||
# display items
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# connection point clock
|
||||
#
|
||||
add_interface clock clock end
|
||||
set_interface_property clock clockRate 0
|
||||
set_interface_property clock ENABLED true
|
||||
set_interface_property clock EXPORT_OF ""
|
||||
set_interface_property clock PORT_NAME_MAP ""
|
||||
set_interface_property clock CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property clock SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port clock clk clk Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point reset
|
||||
#
|
||||
add_interface reset reset end
|
||||
set_interface_property reset associatedClock clock
|
||||
set_interface_property reset synchronousEdges DEASSERT
|
||||
set_interface_property reset ENABLED true
|
||||
set_interface_property reset EXPORT_OF ""
|
||||
set_interface_property reset PORT_NAME_MAP ""
|
||||
set_interface_property reset CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property reset SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port reset reset reset Input 1
|
||||
|
||||
|
||||
#
|
||||
# connection point ctrl
|
||||
#
|
||||
add_interface ctrl avalon end
|
||||
set_interface_property ctrl addressUnits WORDS
|
||||
set_interface_property ctrl associatedClock clock
|
||||
set_interface_property ctrl associatedReset reset
|
||||
set_interface_property ctrl bitsPerSymbol 8
|
||||
set_interface_property ctrl burstOnBurstBoundariesOnly false
|
||||
set_interface_property ctrl burstcountUnits WORDS
|
||||
set_interface_property ctrl explicitAddressSpan 0
|
||||
set_interface_property ctrl holdTime 0
|
||||
set_interface_property ctrl linewrapBursts false
|
||||
set_interface_property ctrl maximumPendingReadTransactions 0
|
||||
set_interface_property ctrl maximumPendingWriteTransactions 0
|
||||
set_interface_property ctrl readLatency 0
|
||||
set_interface_property ctrl readWaitTime 1
|
||||
set_interface_property ctrl setupTime 0
|
||||
set_interface_property ctrl timingUnits Cycles
|
||||
set_interface_property ctrl writeWaitTime 0
|
||||
set_interface_property ctrl ENABLED true
|
||||
set_interface_property ctrl EXPORT_OF ""
|
||||
set_interface_property ctrl PORT_NAME_MAP ""
|
||||
set_interface_property ctrl CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property ctrl SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port ctrl ctrl_address address Input 4
|
||||
add_interface_port ctrl ctrl_read read Input 1
|
||||
add_interface_port ctrl ctrl_readdata readdata Output 32
|
||||
add_interface_port ctrl ctrl_write write Input 1
|
||||
add_interface_port ctrl ctrl_writedata writedata Input 32
|
||||
set_interface_assignment ctrl embeddedsw.configuration.isFlash 0
|
||||
set_interface_assignment ctrl embeddedsw.configuration.isMemoryDevice 0
|
||||
set_interface_assignment ctrl embeddedsw.configuration.isNonVolatileStorage 0
|
||||
set_interface_assignment ctrl embeddedsw.configuration.isPrintableDevice 0
|
||||
|
||||
|
||||
#
|
||||
# connection point hw_sink
|
||||
#
|
||||
add_interface hw_sink avalon end
|
||||
set_interface_property hw_sink addressUnits WORDS
|
||||
set_interface_property hw_sink associatedClock clock
|
||||
set_interface_property hw_sink associatedReset reset
|
||||
set_interface_property hw_sink bitsPerSymbol 8
|
||||
set_interface_property hw_sink burstOnBurstBoundariesOnly false
|
||||
set_interface_property hw_sink burstcountUnits WORDS
|
||||
set_interface_property hw_sink explicitAddressSpan 0
|
||||
set_interface_property hw_sink holdTime 0
|
||||
set_interface_property hw_sink linewrapBursts false
|
||||
set_interface_property hw_sink maximumPendingReadTransactions 0
|
||||
set_interface_property hw_sink maximumPendingWriteTransactions 0
|
||||
set_interface_property hw_sink readLatency 0
|
||||
set_interface_property hw_sink readWaitTime 1
|
||||
set_interface_property hw_sink setupTime 0
|
||||
set_interface_property hw_sink timingUnits Cycles
|
||||
set_interface_property hw_sink writeWaitTime 0
|
||||
set_interface_property hw_sink ENABLED true
|
||||
set_interface_property hw_sink EXPORT_OF ""
|
||||
set_interface_property hw_sink PORT_NAME_MAP ""
|
||||
set_interface_property hw_sink CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property hw_sink SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port hw_sink hw_sink_write write Input 1
|
||||
add_interface_port hw_sink hw_sink_writedata writedata Input 32
|
||||
set_interface_assignment hw_sink embeddedsw.configuration.isFlash 0
|
||||
set_interface_assignment hw_sink embeddedsw.configuration.isMemoryDevice 0
|
||||
set_interface_assignment hw_sink embeddedsw.configuration.isNonVolatileStorage 0
|
||||
set_interface_assignment hw_sink embeddedsw.configuration.isPrintableDevice 0
|
||||
|
||||
|
||||
#
|
||||
# connection point hw_source
|
||||
#
|
||||
add_interface hw_source avalon end
|
||||
set_interface_property hw_source addressUnits WORDS
|
||||
set_interface_property hw_source associatedClock clock
|
||||
set_interface_property hw_source associatedReset reset
|
||||
set_interface_property hw_source bitsPerSymbol 8
|
||||
set_interface_property hw_source burstOnBurstBoundariesOnly false
|
||||
set_interface_property hw_source burstcountUnits WORDS
|
||||
set_interface_property hw_source explicitAddressSpan 0
|
||||
set_interface_property hw_source holdTime 0
|
||||
set_interface_property hw_source linewrapBursts false
|
||||
set_interface_property hw_source maximumPendingReadTransactions 0
|
||||
set_interface_property hw_source maximumPendingWriteTransactions 0
|
||||
set_interface_property hw_source readLatency 0
|
||||
set_interface_property hw_source readWaitTime 1
|
||||
set_interface_property hw_source setupTime 0
|
||||
set_interface_property hw_source timingUnits Cycles
|
||||
set_interface_property hw_source writeWaitTime 0
|
||||
set_interface_property hw_source ENABLED true
|
||||
set_interface_property hw_source EXPORT_OF ""
|
||||
set_interface_property hw_source PORT_NAME_MAP ""
|
||||
set_interface_property hw_source CMSIS_SVD_VARIABLES ""
|
||||
set_interface_property hw_source SVD_ADDRESS_GROUP ""
|
||||
|
||||
add_interface_port hw_source hw_source_read read Input 1
|
||||
add_interface_port hw_source hw_source_readdata readdata Output 32
|
||||
set_interface_assignment hw_source embeddedsw.configuration.isFlash 0
|
||||
set_interface_assignment hw_source embeddedsw.configuration.isMemoryDevice 0
|
||||
set_interface_assignment hw_source embeddedsw.configuration.isNonVolatileStorage 0
|
||||
set_interface_assignment hw_source embeddedsw.configuration.isPrintableDevice 0
|
||||
|
32
hardware/signal_processing.sdc
Normal file
32
hardware/signal_processing.sdc
Normal file
@ -0,0 +1,32 @@
|
||||
# External clock clk_50 has a frequency of 50 MHz
|
||||
create_clock -period 20 [get_ports clk_input]
|
||||
|
||||
derive_pll_clocks
|
||||
|
||||
set clk_main u_pll_200|pll_200|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk
|
||||
|
||||
# Input delays for singals in 50 MHz domain
|
||||
set_input_delay \
|
||||
-clock { clk_input } \
|
||||
2 \
|
||||
[get_ports {reset_n}]
|
||||
|
||||
# Input delays for singals in 200 MHz domain
|
||||
set_false_path \
|
||||
-from \
|
||||
[get_ports {key_start}]
|
||||
|
||||
# Output delays for singals in 200 MHz domain
|
||||
set_false_path \
|
||||
-to \
|
||||
[get_ports { \
|
||||
leds[0] \
|
||||
leds[1] \
|
||||
leds[2] \
|
||||
leds[3] \
|
||||
leds[4] \
|
||||
leds[5] \
|
||||
leds[6] \
|
||||
leds[7] \
|
||||
}]
|
||||
|
77
hardware/signal_processing/add.vhd
Normal file
77
hardware/signal_processing/add.vhd
Normal file
@ -0,0 +1,77 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.reg32.all;
|
||||
use work.task.all;
|
||||
|
||||
entity add is
|
||||
port (
|
||||
clk : in std_logic;
|
||||
reset : in std_logic;
|
||||
|
||||
task_start : in std_logic;
|
||||
task_state : out work.task.State;
|
||||
|
||||
signal_a_read : out std_logic;
|
||||
signal_a_readdata : in std_logic_vector( 31 downto 0 );
|
||||
|
||||
signal_b_read : out std_logic;
|
||||
signal_b_readdata : in std_logic_vector( 31 downto 0 );
|
||||
|
||||
signal_write : out std_logic;
|
||||
signal_writedata : out std_logic_vector( 31 downto 0 )
|
||||
);
|
||||
end entity add;
|
||||
|
||||
architecture rtl of add is
|
||||
signal current_task_state : work.task.State;
|
||||
signal next_task_state : work.task.State;
|
||||
signal index : integer range 0 to work.task.STREAM_LEN;
|
||||
|
||||
begin
|
||||
task_state_transitions : process ( current_task_state, task_start, index ) is
|
||||
begin
|
||||
next_task_state <= current_task_state;
|
||||
case current_task_state is
|
||||
when work.task.TASK_IDLE =>
|
||||
if ( task_start = '1' ) then
|
||||
next_task_state <= work.task.TASK_RUNNING;
|
||||
end if;
|
||||
when work.task.TASK_RUNNING =>
|
||||
if ( index = work.task.STREAM_LEN - 1 ) then
|
||||
next_task_state <= work.task.TASK_DONE;
|
||||
end if;
|
||||
when work.task.TASK_DONE =>
|
||||
if ( task_start = '1' ) then
|
||||
next_task_state <= work.task.TASK_RUNNING;
|
||||
end if;
|
||||
end case;
|
||||
end process task_state_transitions;
|
||||
|
||||
sync : process ( clk, reset ) is
|
||||
begin
|
||||
if ( reset = '1' ) then
|
||||
current_task_state <= work.task.TASK_IDLE;
|
||||
index <= 0;
|
||||
elsif ( rising_edge( clk ) ) then
|
||||
current_task_state <= next_task_state;
|
||||
case next_task_state is
|
||||
when work.task.TASK_IDLE =>
|
||||
index <= 0;
|
||||
signal_write <= '0';
|
||||
when work.task.TASK_RUNNING =>
|
||||
index <= index + 1;
|
||||
signal_write <= '1';
|
||||
signal_writedata <= ( others => '0' );
|
||||
when work.task.TASK_DONE =>
|
||||
index <= 0;
|
||||
signal_write <= '0';
|
||||
end case;
|
||||
end if;
|
||||
end process sync;
|
||||
|
||||
task_state <= current_task_state;
|
||||
|
||||
end architecture rtl;
|
76
hardware/signal_processing/crc.vhd
Normal file
76
hardware/signal_processing/crc.vhd
Normal file
@ -0,0 +1,76 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.reg32.all;
|
||||
use work.task.all;
|
||||
|
||||
entity crc is
|
||||
port (
|
||||
clk : in std_logic;
|
||||
reset : in std_logic;
|
||||
|
||||
task_start : in std_logic;
|
||||
task_state : out work.task.State;
|
||||
|
||||
signal_read : out std_logic;
|
||||
signal_readdata : in std_logic_vector( 31 downto 0 );
|
||||
|
||||
signal_write : out std_logic;
|
||||
signal_writedata : out std_logic_vector( 31 downto 0 )
|
||||
);
|
||||
end entity crc;
|
||||
|
||||
architecture rtl of crc is
|
||||
|
||||
signal current_task_state : work.task.State;
|
||||
signal next_task_state : work.task.State;
|
||||
signal index : integer range 0 to work.task.STREAM_LEN;
|
||||
|
||||
begin
|
||||
task_state_transitions : process ( current_task_state, task_start, index ) is
|
||||
begin
|
||||
next_task_state <= current_task_state;
|
||||
case current_task_state is
|
||||
when work.task.TASK_IDLE =>
|
||||
if ( task_start = '1' ) then
|
||||
next_task_state <= work.task.TASK_RUNNING;
|
||||
end if;
|
||||
when work.task.TASK_RUNNING =>
|
||||
if ( index = work.task.STREAM_LEN - 1 ) then
|
||||
next_task_state <= work.task.TASK_DONE;
|
||||
end if;
|
||||
when work.task.TASK_DONE =>
|
||||
if ( task_start = '1' ) then
|
||||
next_task_state <= work.task.TASK_RUNNING;
|
||||
end if;
|
||||
end case;
|
||||
end process task_state_transitions;
|
||||
|
||||
sync : process ( clk, reset ) is
|
||||
begin
|
||||
if ( reset = '1' ) then
|
||||
current_task_state <= work.task.TASK_IDLE;
|
||||
index <= 0;
|
||||
elsif ( rising_edge( clk ) ) then
|
||||
current_task_state <= next_task_state;
|
||||
case next_task_state is
|
||||
when work.task.TASK_IDLE =>
|
||||
index <= 0;
|
||||
signal_write <= '0';
|
||||
when work.task.TASK_RUNNING =>
|
||||
index <= index + 1;
|
||||
signal_write <= '1';
|
||||
signal_writedata <= ( others => '0' );
|
||||
when work.task.TASK_DONE =>
|
||||
index <= 0;
|
||||
signal_write <= '0';
|
||||
end case;
|
||||
end if;
|
||||
end process sync;
|
||||
|
||||
task_state <= current_task_state;
|
||||
|
||||
end architecture rtl;
|
||||
|
97
hardware/signal_processing/fft.vhd
Normal file
97
hardware/signal_processing/fft.vhd
Normal file
@ -0,0 +1,97 @@
|
||||
------------------------------------------------------------------------
|
||||
-- fft
|
||||
--
|
||||
-- calculation of FFT magnitude
|
||||
--
|
||||
-- Inputs:
|
||||
-- 32-Bit Floating Point number in range +-16 expected (loaded from FIFO)
|
||||
--
|
||||
-- Outputs
|
||||
-- 32-Bit Floating Point number in range +-16 calculated (stored in FIFO)
|
||||
--
|
||||
-----------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.reg32.all;
|
||||
use work.task.all;
|
||||
use work.float.all;
|
||||
|
||||
entity fft is
|
||||
generic (
|
||||
|
||||
-- input data width of real/img part
|
||||
input_data_width : integer := 32;
|
||||
|
||||
-- output data width of real/img part
|
||||
output_data_width : integer := 32
|
||||
|
||||
);
|
||||
port (
|
||||
clk : in std_logic;
|
||||
reset : in std_logic;
|
||||
|
||||
task_start : in std_logic;
|
||||
task_state : out work.task.State;
|
||||
|
||||
signal_read : out std_logic;
|
||||
signal_readdata : in std_logic_vector( 31 downto 0 );
|
||||
|
||||
signal_write : out std_logic;
|
||||
signal_writedata : out std_logic_vector( 31 downto 0 )
|
||||
);
|
||||
end entity fft;
|
||||
|
||||
architecture rtl of fft is
|
||||
|
||||
signal current_task_state : work.task.State;
|
||||
signal next_task_state : work.task.State;
|
||||
signal index : integer range 0 to work.task.STREAM_LEN;
|
||||
|
||||
begin
|
||||
task_state_transitions : process ( current_task_state, task_start, index ) is
|
||||
begin
|
||||
next_task_state <= current_task_state;
|
||||
case current_task_state is
|
||||
when work.task.TASK_IDLE =>
|
||||
if ( task_start = '1' ) then
|
||||
next_task_state <= work.task.TASK_RUNNING;
|
||||
end if;
|
||||
when work.task.TASK_RUNNING =>
|
||||
if ( index = work.task.STREAM_LEN - 1 ) then
|
||||
next_task_state <= work.task.TASK_DONE;
|
||||
end if;
|
||||
when work.task.TASK_DONE =>
|
||||
if ( task_start = '1' ) then
|
||||
next_task_state <= work.task.TASK_RUNNING;
|
||||
end if;
|
||||
end case;
|
||||
end process task_state_transitions;
|
||||
|
||||
sync : process ( clk, reset ) is
|
||||
begin
|
||||
if ( reset = '1' ) then
|
||||
current_task_state <= work.task.TASK_IDLE;
|
||||
index <= 0;
|
||||
elsif ( rising_edge( clk ) ) then
|
||||
current_task_state <= next_task_state;
|
||||
case next_task_state is
|
||||
when work.task.TASK_IDLE =>
|
||||
index <= 0;
|
||||
signal_write <= '0';
|
||||
when work.task.TASK_RUNNING =>
|
||||
index <= index + 1;
|
||||
signal_write <= '1';
|
||||
signal_writedata <= ( others => '0' );
|
||||
when work.task.TASK_DONE =>
|
||||
index <= 0;
|
||||
signal_write <= '0';
|
||||
end case;
|
||||
end if;
|
||||
end process sync;
|
||||
|
||||
task_state <= current_task_state;
|
||||
|
||||
end architecture rtl;
|
73
hardware/signal_processing/rand.vhd
Normal file
73
hardware/signal_processing/rand.vhd
Normal file
@ -0,0 +1,73 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.reg32.all;
|
||||
use work.task.all;
|
||||
|
||||
entity rand is
|
||||
port (
|
||||
clk : in std_logic;
|
||||
reset : in std_logic;
|
||||
|
||||
task_start : in std_logic;
|
||||
task_state : out work.task.State;
|
||||
seed : in work.reg32.word;
|
||||
|
||||
signal_write : out std_logic;
|
||||
signal_writedata : out std_logic_vector( 31 downto 0 )
|
||||
);
|
||||
end entity rand;
|
||||
|
||||
architecture rtl of rand is
|
||||
|
||||
signal current_task_state : work.task.State;
|
||||
signal next_task_state : work.task.State;
|
||||
signal index : integer range 0 to work.task.STREAM_LEN;
|
||||
|
||||
begin
|
||||
task_state_transitions : process ( current_task_state, task_start, index ) is
|
||||
begin
|
||||
next_task_state <= current_task_state;
|
||||
case current_task_state is
|
||||
when work.task.TASK_IDLE =>
|
||||
if ( task_start = '1' ) then
|
||||
next_task_state <= work.task.TASK_RUNNING;
|
||||
end if;
|
||||
when work.task.TASK_RUNNING =>
|
||||
if ( index = work.task.STREAM_LEN - 1 ) then
|
||||
next_task_state <= work.task.TASK_DONE;
|
||||
end if;
|
||||
when work.task.TASK_DONE =>
|
||||
if ( task_start = '1' ) then
|
||||
next_task_state <= work.task.TASK_RUNNING;
|
||||
end if;
|
||||
end case;
|
||||
end process task_state_transitions;
|
||||
|
||||
sync : process ( clk, reset ) is
|
||||
begin
|
||||
if ( reset = '1' ) then
|
||||
current_task_state <= work.task.TASK_IDLE;
|
||||
index <= 0;
|
||||
elsif ( rising_edge( clk ) ) then
|
||||
current_task_state <= next_task_state;
|
||||
case next_task_state is
|
||||
when work.task.TASK_IDLE =>
|
||||
index <= 0;
|
||||
signal_write <= '0';
|
||||
when work.task.TASK_RUNNING =>
|
||||
index <= index + 1;
|
||||
signal_write <= '1';
|
||||
signal_writedata <= ( others => '0' );
|
||||
when work.task.TASK_DONE =>
|
||||
index <= 0;
|
||||
signal_write <= '0';
|
||||
end case;
|
||||
end if;
|
||||
end process sync;
|
||||
|
||||
task_state <= current_task_state;
|
||||
|
||||
end architecture rtl;
|
363
hardware/signal_processing/signal_processing.vhd
Normal file
363
hardware/signal_processing/signal_processing.vhd
Normal file
@ -0,0 +1,363 @@
|
||||
--! Use ieee library for std_logic types.
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
--! Use the niosII library for all processor system components
|
||||
library niosII;
|
||||
|
||||
--! Use the pll_200 library for the PLL 200 MHz clock generation
|
||||
library pll_main;
|
||||
|
||||
entity signal_processing is
|
||||
port
|
||||
(
|
||||
clk_input : in std_logic;
|
||||
reset_n : in std_logic;
|
||||
|
||||
--! Push button key_0 used to start a single execution of the signal
|
||||
--! processing.
|
||||
key_start : in std_logic;
|
||||
|
||||
leds : out std_logic_vector( 7 downto 0 )
|
||||
);
|
||||
end entity signal_processing;
|
||||
|
||||
architecture struct of signal_processing is
|
||||
|
||||
--! input clock synchronous reset
|
||||
signal sync_reset : std_logic;
|
||||
|
||||
--! main clock for the NiosII system
|
||||
signal clk_main : std_logic;
|
||||
--! main clock from PLL is locked and the system reset can be released.
|
||||
signal locked_main : std_logic;
|
||||
--! main clock synchronous reset
|
||||
signal sync_reset_main : std_logic;
|
||||
signal sync_reset_main_n : std_logic;
|
||||
|
||||
signal sw_leds : std_logic_vector( 7 downto 0 );
|
||||
signal hw_leds : std_logic_vector( 7 downto 0 );
|
||||
|
||||
signal hardware_task_0_address : std_logic_vector(3 downto 0);
|
||||
signal hardware_task_0_read : std_logic;
|
||||
signal hardware_task_0_readdata : std_logic_vector(31 downto 0);
|
||||
signal hardware_task_0_write : std_logic;
|
||||
signal hardware_task_0_writedata : std_logic_vector(31 downto 0);
|
||||
|
||||
signal hardware_task_1_address : std_logic_vector(3 downto 0);
|
||||
signal hardware_task_1_read : std_logic;
|
||||
signal hardware_task_1_readdata : std_logic_vector(31 downto 0);
|
||||
signal hardware_task_1_write : std_logic;
|
||||
signal hardware_task_1_writedata : std_logic_vector(31 downto 0);
|
||||
|
||||
signal hardware_task_2_address : std_logic_vector(3 downto 0);
|
||||
signal hardware_task_2_read : std_logic;
|
||||
signal hardware_task_2_readdata : std_logic_vector(31 downto 0);
|
||||
signal hardware_task_2_write : std_logic;
|
||||
signal hardware_task_2_writedata : std_logic_vector(31 downto 0);
|
||||
|
||||
signal hardware_task_3_address : std_logic_vector(3 downto 0);
|
||||
signal hardware_task_3_read : std_logic;
|
||||
signal hardware_task_3_readdata : std_logic_vector(31 downto 0);
|
||||
signal hardware_task_3_write : std_logic;
|
||||
signal hardware_task_3_writedata : std_logic_vector(31 downto 0);
|
||||
|
||||
signal hardware_task_4_address : std_logic_vector(3 downto 0);
|
||||
signal hardware_task_4_read : std_logic;
|
||||
signal hardware_task_4_readdata : std_logic_vector(31 downto 0);
|
||||
signal hardware_task_4_write : std_logic;
|
||||
signal hardware_task_4_writedata : std_logic_vector(31 downto 0);
|
||||
|
||||
signal hardware_task_5_address : std_logic_vector(3 downto 0);
|
||||
signal hardware_task_5_read : std_logic;
|
||||
signal hardware_task_5_readdata : std_logic_vector(31 downto 0);
|
||||
signal hardware_task_5_write : std_logic;
|
||||
signal hardware_task_5_writedata : std_logic_vector(31 downto 0);
|
||||
|
||||
signal hardware_task_6_address : std_logic_vector(3 downto 0);
|
||||
signal hardware_task_6_read : std_logic;
|
||||
signal hardware_task_6_readdata : std_logic_vector(31 downto 0);
|
||||
signal hardware_task_6_write : std_logic;
|
||||
signal hardware_task_6_writedata : std_logic_vector(31 downto 0);
|
||||
|
||||
signal data_channel_0_hw_sink_write : std_logic;
|
||||
signal data_channel_0_hw_sink_writedata : std_logic_vector(31 downto 0);
|
||||
signal data_channel_0_hw_source_read : std_logic;
|
||||
signal data_channel_0_hw_source_readdata : std_logic_vector(31 downto 0);
|
||||
|
||||
signal data_channel_1_hw_sink_write : std_logic;
|
||||
signal data_channel_1_hw_sink_writedata : std_logic_vector(31 downto 0);
|
||||
signal data_channel_1_hw_source_read : std_logic;
|
||||
signal data_channel_1_hw_source_readdata : std_logic_vector(31 downto 0);
|
||||
|
||||
signal data_channel_2_hw_sink_write : std_logic;
|
||||
signal data_channel_2_hw_sink_writedata : std_logic_vector(31 downto 0);
|
||||
signal data_channel_2_hw_source_read : std_logic;
|
||||
signal data_channel_2_hw_source_readdata : std_logic_vector(31 downto 0);
|
||||
|
||||
signal data_channel_3_hw_sink_write : std_logic;
|
||||
signal data_channel_3_hw_sink_writedata : std_logic_vector(31 downto 0);
|
||||
signal data_channel_3_hw_source_read : std_logic;
|
||||
signal data_channel_3_hw_source_readdata : std_logic_vector(31 downto 0);
|
||||
|
||||
signal data_channel_4_hw_sink_write : std_logic;
|
||||
signal data_channel_4_hw_sink_writedata : std_logic_vector(31 downto 0);
|
||||
signal data_channel_4_hw_source_read : std_logic;
|
||||
signal data_channel_4_hw_source_readdata : std_logic_vector(31 downto 0);
|
||||
|
||||
signal data_channel_5_hw_sink_write : std_logic;
|
||||
signal data_channel_5_hw_sink_writedata : std_logic_vector(31 downto 0);
|
||||
signal data_channel_5_hw_source_read : std_logic;
|
||||
signal data_channel_5_hw_source_readdata : std_logic_vector(31 downto 0);
|
||||
|
||||
signal data_channel_6_hw_sink_write : std_logic;
|
||||
signal data_channel_6_hw_sink_writedata : std_logic_vector(31 downto 0);
|
||||
signal data_channel_6_hw_source_read : std_logic;
|
||||
signal data_channel_6_hw_source_readdata : std_logic_vector(31 downto 0);
|
||||
begin
|
||||
|
||||
-- Synchronize the external reset to the external clock domain
|
||||
u_sync_rst_50: entity work.sync_rst
|
||||
port map
|
||||
(
|
||||
clk => clk_input,
|
||||
reset => not reset_n,
|
||||
rst_sync => sync_reset
|
||||
);
|
||||
|
||||
-- PLL for the main system clock
|
||||
u_pll_main: entity pll_main.pll_main
|
||||
port map
|
||||
(
|
||||
refclk => clk_input, -- in std_logic
|
||||
rst => sync_reset, -- in std_logic
|
||||
outclk_0 => clk_main, -- out std_logic
|
||||
locked => locked_main -- out std_logic
|
||||
);
|
||||
|
||||
-- Synchronize the main reset to the main clock domain
|
||||
u_sync_rst_main: entity work.sync_rst
|
||||
port map
|
||||
(
|
||||
clk => clk_main,
|
||||
reset => not locked_main and sync_reset,
|
||||
rst_sync => sync_reset_main
|
||||
);
|
||||
sync_reset_main_n <= not sync_reset_main;
|
||||
|
||||
-- NiosII system
|
||||
u_niosII : entity niosii.niosII
|
||||
port map
|
||||
(
|
||||
clk_clk => clk_main,
|
||||
reset_reset_n => sync_reset_main_n,
|
||||
|
||||
key_start_export => key_start,
|
||||
leds_export => sw_leds,
|
||||
|
||||
data_channel_0_hw_sink_write => data_channel_0_hw_sink_write,
|
||||
data_channel_0_hw_sink_writedata => data_channel_0_hw_sink_writedata,
|
||||
data_channel_0_hw_source_read => data_channel_0_hw_source_read,
|
||||
data_channel_0_hw_source_readdata => data_channel_0_hw_source_readdata,
|
||||
|
||||
data_channel_1_hw_sink_write => data_channel_1_hw_sink_write,
|
||||
data_channel_1_hw_sink_writedata => data_channel_1_hw_sink_writedata,
|
||||
data_channel_1_hw_source_read => data_channel_1_hw_source_read,
|
||||
data_channel_1_hw_source_readdata => data_channel_1_hw_source_readdata,
|
||||
|
||||
data_channel_2_hw_sink_write => data_channel_2_hw_sink_write,
|
||||
data_channel_2_hw_sink_writedata => data_channel_2_hw_sink_writedata,
|
||||
data_channel_2_hw_source_read => data_channel_2_hw_source_read,
|
||||
data_channel_2_hw_source_readdata => data_channel_2_hw_source_readdata,
|
||||
|
||||
data_channel_3_hw_sink_write => data_channel_3_hw_sink_write,
|
||||
data_channel_3_hw_sink_writedata => data_channel_3_hw_sink_writedata,
|
||||
data_channel_3_hw_source_read => data_channel_3_hw_source_read,
|
||||
data_channel_3_hw_source_readdata => data_channel_3_hw_source_readdata,
|
||||
|
||||
data_channel_4_hw_sink_write => data_channel_4_hw_sink_write,
|
||||
data_channel_4_hw_sink_writedata => data_channel_4_hw_sink_writedata,
|
||||
data_channel_4_hw_source_read => data_channel_4_hw_source_read,
|
||||
data_channel_4_hw_source_readdata => data_channel_4_hw_source_readdata,
|
||||
|
||||
data_channel_5_hw_sink_write => data_channel_5_hw_sink_write,
|
||||
data_channel_5_hw_sink_writedata => data_channel_5_hw_sink_writedata,
|
||||
data_channel_5_hw_source_read => data_channel_5_hw_source_read,
|
||||
data_channel_5_hw_source_readdata => data_channel_5_hw_source_readdata,
|
||||
|
||||
data_channel_6_hw_sink_write => data_channel_6_hw_sink_write,
|
||||
data_channel_6_hw_sink_writedata => data_channel_6_hw_sink_writedata,
|
||||
data_channel_6_hw_source_read => data_channel_6_hw_source_read,
|
||||
data_channel_6_hw_source_readdata => data_channel_6_hw_source_readdata,
|
||||
|
||||
hardware_task_0_task_address => hardware_task_0_address,
|
||||
hardware_task_0_task_read => hardware_task_0_read,
|
||||
hardware_task_0_task_readdata => hardware_task_0_readdata,
|
||||
hardware_task_0_task_write => hardware_task_0_write,
|
||||
hardware_task_0_task_writedata => hardware_task_0_writedata,
|
||||
|
||||
hardware_task_1_task_address => hardware_task_1_address,
|
||||
hardware_task_1_task_read => hardware_task_1_read,
|
||||
hardware_task_1_task_readdata => hardware_task_1_readdata,
|
||||
hardware_task_1_task_write => hardware_task_1_write,
|
||||
hardware_task_1_task_writedata => hardware_task_1_writedata,
|
||||
|
||||
hardware_task_2_task_address => hardware_task_2_address,
|
||||
hardware_task_2_task_read => hardware_task_2_read,
|
||||
hardware_task_2_task_readdata => hardware_task_2_readdata,
|
||||
hardware_task_2_task_write => hardware_task_2_write,
|
||||
hardware_task_2_task_writedata => hardware_task_2_writedata,
|
||||
|
||||
hardware_task_3_task_address => hardware_task_3_address,
|
||||
hardware_task_3_task_read => hardware_task_3_read,
|
||||
hardware_task_3_task_readdata => hardware_task_3_readdata,
|
||||
hardware_task_3_task_write => hardware_task_3_write,
|
||||
hardware_task_3_task_writedata => hardware_task_3_writedata,
|
||||
|
||||
hardware_task_4_task_address => hardware_task_4_address,
|
||||
hardware_task_4_task_read => hardware_task_4_read,
|
||||
hardware_task_4_task_readdata => hardware_task_4_readdata,
|
||||
hardware_task_4_task_write => hardware_task_4_write,
|
||||
hardware_task_4_task_writedata => hardware_task_4_writedata,
|
||||
|
||||
hardware_task_5_task_address => hardware_task_5_address,
|
||||
hardware_task_5_task_read => hardware_task_5_read,
|
||||
hardware_task_5_task_readdata => hardware_task_5_readdata,
|
||||
hardware_task_5_task_write => hardware_task_5_write,
|
||||
hardware_task_5_task_writedata => hardware_task_5_writedata,
|
||||
|
||||
hardware_task_6_task_address => hardware_task_6_address,
|
||||
hardware_task_6_task_read => hardware_task_6_read,
|
||||
hardware_task_6_task_readdata => hardware_task_6_readdata,
|
||||
hardware_task_6_task_write => hardware_task_6_write,
|
||||
hardware_task_6_task_writedata => hardware_task_6_writedata
|
||||
);
|
||||
|
||||
u_task_sine: entity work.task_sine
|
||||
port map (
|
||||
clk => clk_main,
|
||||
reset => sync_reset_main,
|
||||
|
||||
address => hardware_task_0_address,
|
||||
read => hardware_task_0_read,
|
||||
readdata => hardware_task_0_readdata,
|
||||
write => hardware_task_0_write,
|
||||
writedata => hardware_task_0_writedata,
|
||||
|
||||
signal_write => data_channel_0_hw_sink_write ,
|
||||
signal_writedata => data_channel_0_hw_sink_writedata
|
||||
);
|
||||
|
||||
u_task_cosine: entity work.task_sine
|
||||
port map (
|
||||
clk => clk_main,
|
||||
reset => sync_reset_main,
|
||||
|
||||
address => hardware_task_1_address,
|
||||
read => hardware_task_1_read,
|
||||
readdata => hardware_task_1_readdata,
|
||||
write => hardware_task_1_write,
|
||||
writedata => hardware_task_1_writedata,
|
||||
|
||||
signal_write => data_channel_1_hw_sink_write ,
|
||||
signal_writedata => data_channel_1_hw_sink_writedata
|
||||
);
|
||||
|
||||
u_task_rand: entity work.task_rand
|
||||
port map (
|
||||
clk => clk_main,
|
||||
reset => sync_reset_main,
|
||||
|
||||
address => hardware_task_2_address,
|
||||
read => hardware_task_2_read,
|
||||
readdata => hardware_task_2_readdata,
|
||||
write => hardware_task_2_write,
|
||||
writedata => hardware_task_2_writedata,
|
||||
|
||||
signal_write => data_channel_2_hw_sink_write ,
|
||||
signal_writedata => data_channel_2_hw_sink_writedata
|
||||
);
|
||||
|
||||
u_task_add_sine_cosine: entity work.task_add
|
||||
port map (
|
||||
clk => clk_main,
|
||||
reset => sync_reset_main,
|
||||
|
||||
address => hardware_task_3_address,
|
||||
read => hardware_task_3_read,
|
||||
readdata => hardware_task_3_readdata,
|
||||
write => hardware_task_3_write,
|
||||
writedata => hardware_task_3_writedata,
|
||||
|
||||
signal_a_read => data_channel_0_hw_source_read,
|
||||
signal_a_readdata => data_channel_0_hw_source_readdata,
|
||||
|
||||
signal_b_read => data_channel_1_hw_source_read,
|
||||
signal_b_readdata => data_channel_1_hw_source_readdata,
|
||||
|
||||
signal_write => data_channel_3_hw_sink_write ,
|
||||
signal_writedata => data_channel_3_hw_sink_writedata
|
||||
);
|
||||
|
||||
u_task_add_rand: entity work.task_add
|
||||
port map (
|
||||
clk => clk_main,
|
||||
reset => sync_reset_main,
|
||||
|
||||
address => hardware_task_4_address,
|
||||
read => hardware_task_4_read,
|
||||
readdata => hardware_task_4_readdata,
|
||||
write => hardware_task_4_write,
|
||||
writedata => hardware_task_4_writedata,
|
||||
|
||||
signal_a_read => data_channel_2_hw_source_read,
|
||||
signal_a_readdata => data_channel_2_hw_source_readdata,
|
||||
|
||||
signal_b_read => data_channel_3_hw_source_read,
|
||||
signal_b_readdata => data_channel_3_hw_source_readdata,
|
||||
|
||||
signal_write => data_channel_4_hw_sink_write ,
|
||||
signal_writedata => data_channel_4_hw_sink_writedata
|
||||
);
|
||||
|
||||
u_task_fft: entity work.task_fft
|
||||
port map (
|
||||
clk => clk_main,
|
||||
reset => sync_reset_main,
|
||||
|
||||
address => hardware_task_5_address,
|
||||
read => hardware_task_5_read,
|
||||
readdata => hardware_task_5_readdata,
|
||||
write => hardware_task_5_write,
|
||||
writedata => hardware_task_5_writedata,
|
||||
|
||||
signal_read => data_channel_4_hw_source_read,
|
||||
signal_readdata => data_channel_4_hw_source_readdata,
|
||||
|
||||
signal_write => data_channel_5_hw_sink_write ,
|
||||
signal_writedata => data_channel_5_hw_sink_writedata
|
||||
);
|
||||
|
||||
u_task_crc: entity work.task_crc
|
||||
port map (
|
||||
clk => clk_main,
|
||||
reset => sync_reset_main,
|
||||
|
||||
address => hardware_task_6_address,
|
||||
read => hardware_task_6_read,
|
||||
readdata => hardware_task_6_readdata,
|
||||
write => hardware_task_6_write,
|
||||
writedata => hardware_task_6_writedata,
|
||||
|
||||
signal_read => data_channel_5_hw_source_read,
|
||||
signal_readdata => data_channel_5_hw_source_readdata,
|
||||
|
||||
signal_write => data_channel_6_hw_sink_write ,
|
||||
signal_writedata => data_channel_6_hw_sink_writedata
|
||||
);
|
||||
|
||||
hw_leds <= ( 0 => reset_n, 1 => sync_reset, 2 => locked_main, 3 => sync_reset_main, others => '0' );
|
||||
leds <= sw_leds or hw_leds;
|
||||
|
||||
end architecture struct;
|
||||
|
77
hardware/signal_processing/sine.vhd
Normal file
77
hardware/signal_processing/sine.vhd
Normal file
@ -0,0 +1,77 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.reg32.all;
|
||||
use work.float.all;
|
||||
use work.task.all;
|
||||
|
||||
entity sine is
|
||||
port (
|
||||
clk : in std_logic;
|
||||
reset : in std_logic;
|
||||
|
||||
task_start : in std_logic;
|
||||
task_state : out work.task.State;
|
||||
|
||||
step_size : in work.reg32.word;
|
||||
phase : in work.reg32.word;
|
||||
amplitude : in work.reg32.word;
|
||||
|
||||
signal_write : out std_logic;
|
||||
signal_writedata : out std_logic_vector( 31 downto 0 )
|
||||
);
|
||||
end entity sine;
|
||||
|
||||
architecture rtl of sine is
|
||||
|
||||
signal current_task_state : work.task.State;
|
||||
signal next_task_state : work.task.State;
|
||||
signal index : integer range 0 to work.task.STREAM_LEN;
|
||||
|
||||
begin
|
||||
task_state_transitions : process ( current_task_state, task_start, index ) is
|
||||
begin
|
||||
next_task_state <= current_task_state;
|
||||
case current_task_state is
|
||||
when work.task.TASK_IDLE =>
|
||||
if ( task_start = '1' ) then
|
||||
next_task_state <= work.task.TASK_RUNNING;
|
||||
end if;
|
||||
when work.task.TASK_RUNNING =>
|
||||
if ( index = work.task.STREAM_LEN - 1 ) then
|
||||
next_task_state <= work.task.TASK_DONE;
|
||||
end if;
|
||||
when work.task.TASK_DONE =>
|
||||
if ( task_start = '1' ) then
|
||||
next_task_state <= work.task.TASK_RUNNING;
|
||||
end if;
|
||||
end case;
|
||||
end process task_state_transitions;
|
||||
|
||||
sync : process ( clk, reset ) is
|
||||
begin
|
||||
if ( reset = '1' ) then
|
||||
current_task_state <= work.task.TASK_IDLE;
|
||||
index <= 0;
|
||||
elsif ( rising_edge( clk ) ) then
|
||||
current_task_state <= next_task_state;
|
||||
case next_task_state is
|
||||
when work.task.TASK_IDLE =>
|
||||
index <= 0;
|
||||
signal_write <= '0';
|
||||
when work.task.TASK_RUNNING =>
|
||||
index <= index + 1;
|
||||
signal_write <= '1';
|
||||
signal_writedata <= ( others => '0' );
|
||||
when work.task.TASK_DONE =>
|
||||
index <= 0;
|
||||
signal_write <= '0';
|
||||
end case;
|
||||
end if;
|
||||
end process sync;
|
||||
|
||||
task_state <= current_task_state;
|
||||
|
||||
end architecture rtl;
|
32
hardware/system/Butterfly.v
Normal file
32
hardware/system/Butterfly.v
Normal file
@ -0,0 +1,32 @@
|
||||
//----------------------------------------------------------------------
|
||||
// Butterfly: Add/Sub and Scaling
|
||||
//----------------------------------------------------------------------
|
||||
module Butterfly #(
|
||||
parameter WIDTH = 16,
|
||||
parameter RH = 0 // Round Half Up
|
||||
)(
|
||||
input signed [WIDTH-1:0] x0_re, // Input Data #0 (Real)
|
||||
input signed [WIDTH-1:0] x0_im, // Input Data #0 (Imag)
|
||||
input signed [WIDTH-1:0] x1_re, // Input Data #1 (Real)
|
||||
input signed [WIDTH-1:0] x1_im, // Input Data #1 (Imag)
|
||||
output signed [WIDTH-1:0] y0_re, // Output Data #0 (Real)
|
||||
output signed [WIDTH-1:0] y0_im, // Output Data #0 (Imag)
|
||||
output signed [WIDTH-1:0] y1_re, // Output Data #1 (Real)
|
||||
output signed [WIDTH-1:0] y1_im // Output Data #1 (Imag)
|
||||
);
|
||||
|
||||
wire signed [WIDTH:0] add_re, add_im, sub_re, sub_im;
|
||||
|
||||
// Add/Sub
|
||||
assign add_re = x0_re + x1_re;
|
||||
assign add_im = x0_im + x1_im;
|
||||
assign sub_re = x0_re - x1_re;
|
||||
assign sub_im = x0_im - x1_im;
|
||||
|
||||
// Scaling
|
||||
assign y0_re = (add_re + RH) >>> 1;
|
||||
assign y0_im = (add_im + RH) >>> 1;
|
||||
assign y1_re = (sub_re + RH) >>> 1;
|
||||
assign y1_im = (sub_im + RH) >>> 1;
|
||||
|
||||
endmodule
|
32
hardware/system/DelayBuffer.v
Normal file
32
hardware/system/DelayBuffer.v
Normal file
@ -0,0 +1,32 @@
|
||||
//----------------------------------------------------------------------
|
||||
// DelayBuffer: Generate Constant Delay
|
||||
//----------------------------------------------------------------------
|
||||
module DelayBuffer #(
|
||||
parameter DEPTH = 32,
|
||||
parameter WIDTH = 16
|
||||
)(
|
||||
input clock, // Master Clock
|
||||
input [WIDTH-1:0] di_re, // Data Input (Real)
|
||||
input [WIDTH-1:0] di_im, // Data Input (Imag)
|
||||
output [WIDTH-1:0] do_re, // Data Output (Real)
|
||||
output [WIDTH-1:0] do_im // Data Output (Imag)
|
||||
);
|
||||
|
||||
reg [WIDTH-1:0] buf_re[0:DEPTH-1];
|
||||
reg [WIDTH-1:0] buf_im[0:DEPTH-1];
|
||||
integer n;
|
||||
|
||||
// Shift Buffer
|
||||
always @(posedge clock) begin
|
||||
for (n = DEPTH-1; n > 0; n = n - 1) begin
|
||||
buf_re[n] <= buf_re[n-1];
|
||||
buf_im[n] <= buf_im[n-1];
|
||||
end
|
||||
buf_re[0] <= di_re;
|
||||
buf_im[0] <= di_im;
|
||||
end
|
||||
|
||||
assign do_re = buf_re[DEPTH-1];
|
||||
assign do_im = buf_im[DEPTH-1];
|
||||
|
||||
endmodule
|
89
hardware/system/FFT1024_32B.v
Normal file
89
hardware/system/FFT1024_32B.v
Normal file
@ -0,0 +1,89 @@
|
||||
//----------------------------------------------------------------------
|
||||
// FFT: 1024-Point FFT Using Radix-2^2 Single-Path Delay Feedback
|
||||
//----------------------------------------------------------------------
|
||||
module FFTMAIN #(
|
||||
parameter WIDTH = 32
|
||||
)(
|
||||
input clock, // Master Clock
|
||||
input reset, // Active High Asynchronous Reset
|
||||
input di_en, // Input Data Enable
|
||||
input [WIDTH-1:0] di_re, // Input Data (Real)
|
||||
input [WIDTH-1:0] di_im, // Input Data (Imag)
|
||||
output do_en, // Output Data Enable
|
||||
output [WIDTH-1:0] do_re, // Output Data (Real)
|
||||
output [WIDTH-1:0] do_im // Output Data (Imag)
|
||||
);
|
||||
//----------------------------------------------------------------------
|
||||
// Data must be input consecutively in natural order.
|
||||
// The result is scaled to 1/N and output in bit-reversed order.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
wire su1_do_en;
|
||||
wire[WIDTH-1:0] su1_do_re;
|
||||
wire[WIDTH-1:0] su1_do_im;
|
||||
wire su2_do_en;
|
||||
wire[WIDTH-1:0] su2_do_re;
|
||||
wire[WIDTH-1:0] su2_do_im;
|
||||
wire su3_do_en;
|
||||
wire[WIDTH-1:0] su3_do_re;
|
||||
wire[WIDTH-1:0] su3_do_im;
|
||||
wire su4_do_en;
|
||||
wire[WIDTH-1:0] su4_do_re;
|
||||
wire[WIDTH-1:0] su4_do_im;
|
||||
|
||||
SdfUnit #(.N(1024),.M(1024),.WIDTH(WIDTH)) SU1 (
|
||||
.clock (clock ), // i
|
||||
.reset (reset ), // i
|
||||
.di_en (di_en ), // i
|
||||
.di_re (di_re ), // i
|
||||
.di_im (di_im ), // i
|
||||
.do_en (su1_do_en ), // o
|
||||
.do_re (su1_do_re ), // o
|
||||
.do_im (su1_do_im ) // o
|
||||
);
|
||||
|
||||
SdfUnit #(.N(1024),.M(256),.WIDTH(WIDTH)) SU2 (
|
||||
.clock (clock ), // i
|
||||
.reset (reset ), // i
|
||||
.di_en (su1_do_en ), // i
|
||||
.di_re (su1_do_re ), // i
|
||||
.di_im (su1_do_im ), // i
|
||||
.do_en (su2_do_en ), // o
|
||||
.do_re (su2_do_re ), // o
|
||||
.do_im (su2_do_im ) // o
|
||||
);
|
||||
|
||||
SdfUnit #(.N(1024),.M(64),.WIDTH(WIDTH)) SU3 (
|
||||
.clock (clock ), // i
|
||||
.reset (reset ), // i
|
||||
.di_en (su2_do_en ), // i
|
||||
.di_re (su2_do_re ), // i
|
||||
.di_im (su2_do_im ), // i
|
||||
.do_en (su3_do_en ), // o
|
||||
.do_re (su3_do_re ), // o
|
||||
.do_im (su3_do_im ) // o
|
||||
);
|
||||
|
||||
SdfUnit #(.N(1024),.M(16),.WIDTH(WIDTH)) SU4 (
|
||||
.clock (clock ), // i
|
||||
.reset (reset ), // i
|
||||
.di_en (su3_do_en ), // i
|
||||
.di_re (su3_do_re ), // i
|
||||
.di_im (su3_do_im ), // i
|
||||
.do_en (su4_do_en ), // o
|
||||
.do_re (su4_do_re ), // o
|
||||
.do_im (su4_do_im ) // o
|
||||
);
|
||||
|
||||
SdfUnit #(.N(1024),.M(4),.WIDTH(WIDTH)) SU5 (
|
||||
.clock (clock ), // i
|
||||
.reset (reset ), // i
|
||||
.di_en (su4_do_en ), // i
|
||||
.di_re (su4_do_re ), // i
|
||||
.di_im (su4_do_im ), // i
|
||||
.do_en (do_en ), // o
|
||||
.do_re (do_re ), // o
|
||||
.do_im (do_im ) // o
|
||||
);
|
||||
|
||||
endmodule
|
35
hardware/system/Multiply.v
Normal file
35
hardware/system/Multiply.v
Normal file
@ -0,0 +1,35 @@
|
||||
//----------------------------------------------------------------------
|
||||
// Multiply: Complex Multiplier
|
||||
//----------------------------------------------------------------------
|
||||
module Multiply #(
|
||||
parameter WIDTH = 16
|
||||
)(
|
||||
input signed [WIDTH-1:0] a_re,
|
||||
input signed [WIDTH-1:0] a_im,
|
||||
input signed [WIDTH-1:0] b_re,
|
||||
input signed [WIDTH-1:0] b_im,
|
||||
output signed [WIDTH-1:0] m_re,
|
||||
output signed [WIDTH-1:0] m_im
|
||||
);
|
||||
|
||||
wire signed [WIDTH*2-1:0] arbr, arbi, aibr, aibi;
|
||||
wire signed [WIDTH-1:0] sc_arbr, sc_arbi, sc_aibr, sc_aibi;
|
||||
|
||||
// Signed Multiplication
|
||||
assign arbr = a_re * b_re;
|
||||
assign arbi = a_re * b_im;
|
||||
assign aibr = a_im * b_re;
|
||||
assign aibi = a_im * b_im;
|
||||
|
||||
// Scaling
|
||||
assign sc_arbr = arbr >>> (WIDTH-1);
|
||||
assign sc_arbi = arbi >>> (WIDTH-1);
|
||||
assign sc_aibr = aibr >>> (WIDTH-1);
|
||||
assign sc_aibi = aibi >>> (WIDTH-1);
|
||||
|
||||
// Sub/Add
|
||||
// These sub/add may overflow if unnormalized data is input.
|
||||
assign m_re = sc_arbr - sc_aibi;
|
||||
assign m_im = sc_arbi + sc_aibr;
|
||||
|
||||
endmodule
|
277
hardware/system/SdfUnit.v
Normal file
277
hardware/system/SdfUnit.v
Normal file
@ -0,0 +1,277 @@
|
||||
//----------------------------------------------------------------------
|
||||
// SdfUnit: Radix-2^2 Single-Path Delay Feedback Unit for N-Point FFT
|
||||
//----------------------------------------------------------------------
|
||||
module SdfUnit #(
|
||||
parameter N = 64, // Number of FFT Point
|
||||
parameter M = 64, // Twiddle Resolution
|
||||
parameter WIDTH = 16 // Data Bit Length
|
||||
)(
|
||||
input clock, // Master Clock
|
||||
input reset, // Active High Asynchronous Reset
|
||||
input di_en, // Input Data Enable
|
||||
input [WIDTH-1:0] di_re, // Input Data (Real)
|
||||
input [WIDTH-1:0] di_im, // Input Data (Imag)
|
||||
output do_en, // Output Data Enable
|
||||
output [WIDTH-1:0] do_re, // Output Data (Real)
|
||||
output [WIDTH-1:0] do_im // Output Data (Imag)
|
||||
);
|
||||
|
||||
// log2 constant function
|
||||
function integer log2;
|
||||
input integer x;
|
||||
integer value;
|
||||
begin
|
||||
value = x-1;
|
||||
for (log2=0; value>0; log2=log2+1)
|
||||
value = value>>1;
|
||||
end
|
||||
endfunction
|
||||
|
||||
localparam LOG_N = log2(N); // Bit Length of N
|
||||
localparam LOG_M = log2(M); // Bit Length of M
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Internal Regs and Nets
|
||||
//------- |