Initial commit

This commit is contained in:
Johannes Kutning 2023-10-31 07:47:27 +01:00
commit 0d1b73e3e0
255 changed files with 16057 additions and 0 deletions

20
.gitignore vendored Normal file
View 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
View 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
View 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

View 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] \
}]

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

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

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

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

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

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

View 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

View 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

View 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

View 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
View 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
//-------