URL
https://opencores.org/ocsvn/ccsds_rxtxsoc/ccsds_rxtxsoc/trunk
Subversion Repositories ccsds_rxtxsoc
Compare Revisions
- This comparison shows the changes necessary to convert path
/ccsds_rxtxsoc/trunk
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/ccsds_rx.vhd
0,0 → 1,126
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_rx |
---- Version: 1.0.0 |
---- Description: |
---- TO BE DONE |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2015/11/17: initial release |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
-- unitary rx external physical inputs and outputs |
entity ccsds_rx is |
generic ( |
CCSDS_RX_PHYS_SIG_QUANT_DEPTH : integer := 16; |
CCSDS_RX_DATA_BUS_SIZE: integer := 32 |
); |
port( |
-- inputs |
clk_i: in std_logic; -- input samples clock |
dat_nxt_i: in std_logic; -- next data |
ena_i: in std_logic; -- system enable input |
rst_i: in std_logic; -- system reset input |
sam_i_i: in std_logic_vector(CCSDS_RX_PHYS_SIG_QUANT_DEPTH-1 downto 0); -- in-phased parallel complex samples |
sam_q_i: in std_logic_vector(CCSDS_RX_PHYS_SIG_QUANT_DEPTH-1 downto 0); -- quadrature-phased parallel complex samples |
-- outputs |
buf_bit_ful_o: out std_logic; -- bits buffer status indicator |
buf_dat_ful_o: out std_logic; -- data buffer status indicator |
buf_fra_ful_o: out std_logic; -- frames buffer status indicator |
dat_o: out std_logic_vector(CCSDS_RX_DATA_BUS_SIZE-1 downto 0); -- received data parallel output |
dat_val_o: out std_logic; -- data valid |
ena_o: out std_logic; -- enabled status indicator |
irq_o: out std_logic -- data ready to be read / IRQ signal |
); |
end ccsds_rx; |
|
architecture structure of ccsds_rx is |
component ccsds_rx_datalink_layer is |
generic( |
CCSDS_RX_DATALINK_DATA_BUS_SIZE : integer |
); |
port( |
clk_i: in std_logic; |
rst_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_RX_DATA_BUS_SIZE-1 downto 0); |
dat_o: out std_logic_vector(CCSDS_RX_DATA_BUS_SIZE-1 downto 0); |
buf_dat_ful_o: out std_logic; |
buf_fra_ful_o: out std_logic; |
buf_bit_ful_o: out std_logic |
); |
end component; |
component ccsds_rx_physical_layer is |
generic( |
CCSDS_RX_PHYSICAL_SIG_QUANT_DEPTH : integer; |
CCSDS_RX_PHYSICAL_DATA_BUS_SIZE : integer |
); |
port( |
clk_i: in std_logic; |
clk_o: out std_logic; |
rst_i: in std_logic; |
sam_i_i: in std_logic_vector(CCSDS_RX_PHYS_SIG_QUANT_DEPTH-1 downto 0); |
sam_q_i: in std_logic_vector(CCSDS_RX_PHYS_SIG_QUANT_DEPTH-1 downto 0); |
dat_o: out std_logic_vector(CCSDS_RX_DATA_BUS_SIZE-1 downto 0) |
); |
end component; |
|
signal wire_data_m: std_logic_vector(CCSDS_RX_DATA_BUS_SIZE-1 downto 0); |
signal wire_clk_m: std_logic; |
signal wire_clk_i: std_logic; |
|
begin |
rx_datalink_layer_1: ccsds_rx_datalink_layer |
generic map( |
CCSDS_RX_DATALINK_DATA_BUS_SIZE => CCSDS_RX_DATA_BUS_SIZE |
) |
port map( |
clk_i => wire_clk_m, |
rst_i => rst_i, |
dat_i => wire_data_m, |
dat_o => dat_o, |
buf_dat_ful_o => buf_dat_ful_o, |
buf_fra_ful_o => buf_fra_ful_o, |
buf_bit_ful_o => buf_bit_ful_o |
); |
rx_physical_layer_1: ccsds_rx_physical_layer |
generic map( |
CCSDS_RX_PHYSICAL_SIG_QUANT_DEPTH => CCSDS_RX_PHYS_SIG_QUANT_DEPTH, |
CCSDS_RX_PHYSICAL_DATA_BUS_SIZE => CCSDS_RX_DATA_BUS_SIZE |
) |
port map( |
clk_i => wire_clk_i, |
clk_o => wire_clk_m, |
rst_i => rst_i, |
sam_i_i => sam_i_i, |
sam_q_i => sam_q_i, |
dat_o => wire_data_m |
); |
|
--============================================================================= |
-- Begin of enablep |
-- Enable/disable clk forwarding |
--============================================================================= |
-- read: clk_i, ena_i |
-- write: wire_clk_i |
-- r/w: |
ENABLEP : process (clk_i, ena_i) |
begin |
if (ena_i = '1') then |
wire_clk_i <= clk_i; |
ena_o <= '1'; |
else |
wire_clk_i <= '0'; |
ena_o <= '0'; |
end if; |
end process; |
end structure; |
/ccsds_rx_datalink_layer.vhd
0,0 → 1,53
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_rx_datalink_layer |
---- Version: 1.0.0 |
---- Description: |
---- TO BE DONE |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2015/11/17: initial release |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
-- unitary rx datalink layer |
entity ccsds_rx_datalink_layer is |
generic ( |
CCSDS_RX_DATALINK_DATA_BUS_SIZE: integer := 32 |
); |
port( |
-- inputs |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_RX_DATALINK_DATA_BUS_SIZE-1 downto 0); |
rst_i: in std_logic; |
-- outputs |
buf_bit_ful_o: out std_logic; |
buf_dat_ful_o: out std_logic; |
buf_fra_ful_o: out std_logic; |
dat_o: out std_logic_vector(CCSDS_RX_DATALINK_DATA_BUS_SIZE-1 downto 0) |
); |
end ccsds_rx_datalink_layer; |
|
-- internal processing |
architecture rtl of ccsds_rx_datalink_layer is |
-- TEMPORARY NO CHANGE / DUMMY LINKLAYER |
|
begin |
dat_o <= dat_i; |
buf_dat_ful_o <= '0'; |
buf_fra_ful_o <= '0'; |
buf_bit_ful_o <= '0'; |
|
DATALINKP : process (clk_i, dat_i) |
begin |
end process; |
end rtl; |
/ccsds_rx_physical_layer.vhd
0,0 → 1,66
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_rx_physical_layer |
---- Version: 1.0.0 |
---- Description: |
---- TO BE DONE |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2015/11/17: initial release |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_rx_physical_layer / unitary rx physical layer |
--============================================================================= |
entity ccsds_rx_physical_layer is |
generic ( |
CCSDS_RX_PHYSICAL_DATA_BUS_SIZE: integer := 32; |
CCSDS_RX_PHYSICAL_SIG_QUANT_DEPTH : integer := 16 |
); |
port( |
-- inputs |
clk_i: in std_logic; |
rst_i: in std_logic; |
sam_i_i: in std_logic_vector(CCSDS_RX_PHYSICAL_SIG_QUANT_DEPTH-1 downto 0); |
sam_q_i: in std_logic_vector(CCSDS_RX_PHYSICAL_SIG_QUANT_DEPTH-1 downto 0); |
-- outputs |
clk_o: out std_logic; |
dat_o: out std_logic_vector(CCSDS_RX_PHYSICAL_DATA_BUS_SIZE-1 downto 0) |
); |
end ccsds_rx_physical_layer; |
|
--============================================================================= |
-- architecture declaration / internal processing |
--============================================================================= |
architecture rtl of ccsds_rx_physical_layer is |
--============================================================================= |
-- architecture begin |
--============================================================================= |
begin |
dat_o(CCSDS_RX_PHYSICAL_DATA_BUS_SIZE-1 downto CCSDS_RX_PHYSICAL_SIG_QUANT_DEPTH) <= sam_q_i; |
dat_o(CCSDS_RX_PHYSICAL_SIG_QUANT_DEPTH-1 downto 0) <= sam_i_i; |
clk_o <= clk_i; |
--============================================================================= |
-- Begin of physicalp |
-- TEST PURPOSES / DUMMY PHYSICAL LAYER PROCESS |
--============================================================================= |
-- read: clk_i |
-- write: |
-- r/w: |
PHYSICALP : process (clk_i) |
begin |
end process; |
end rtl; |
--============================================================================= |
-- architecture end |
--============================================================================= |
/ccsds_rxtx.core
0,0 → 1,48
CAPI=1 |
[main] |
description = EurySPACE CCSDS RX/TX with wishbone interface |
simulators = ghdl |
|
[fileset rtl_files] |
files = |
ccsds_rxtx_buffer.vhd |
ccsds_rxtx_clock_divider.vhd |
ccsds_rxtx_constants.vhd |
ccsds_rxtx_crc.vhd |
ccsds_rxtx_functions.vhd |
ccsds_rxtx_lfsr.vhd |
ccsds_rxtx_oversampler.vhd |
ccsds_rxtx_parameters.vhd |
ccsds_rxtx_serdes.vhd |
ccsds_rxtx_srrc.vhd |
ccsds_rxtx_top.vhd |
ccsds_rxtx_types.vhd |
ccsds_rx.vhd |
ccsds_rx_datalink_layer.vhd |
ccsds_rx_physical_layer.vhd |
ccsds_tx.vhd |
ccsds_tx_coder.vhd |
ccsds_tx_coder_convolutional.vhd |
ccsds_tx_coder_differential.vhd |
ccsds_tx_datalink_layer.vhd |
ccsds_tx_filter.vhd |
ccsds_tx_footer.vhd |
ccsds_tx_framer.vhd |
ccsds_tx_header.vhd |
ccsds_tx_manager.vhd |
ccsds_tx_mapper_bits_symbols.vhd |
ccsds_tx_mapper_symbols_samples.vhd |
ccsds_tx_physical_layer.vhd |
ccsds_tx_randomizer.vhd |
ccsds_tx_synchronizer.vhd |
file_type = vhdlSource |
usage = sim synth |
|
[fileset tb] |
files = ccsds_rxtx_bench.vhd |
file_type = vhdlSource |
scope = private |
usage = sim |
|
[simulator] |
toplevel = ccsds_rxtx_bench |
/ccsds_rxtx_bench.vhd
0,0 → 1,2767
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_rxtx_bench |
---- Version: 1.0.0 |
---- Description: |
---- Unit level + sub-components testing vhdl ressource |
---- 1: generate clock signals |
---- 2: generate resets signals |
---- 3: generate wb read/write cycles signals |
---- 4: generate rx/tx external data and samples signals |
---- 5: generate test sequences for sub-components |
---- 6: store signals results as ASCII files |
------------------------------- |
---- Author(s): |
---- Guillaume Rembert |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2015/11/18: initial release |
---- 2015/12/28: adding random stimuli generation |
---- 2016/10/19: adding sub-components (CRC + buffer) test ressources |
---- 2016/10/25: adding framer sub-component test ressources + CRC checks |
---- 2016/10/27: adding serdes sub-component test ressources |
---- 2016/10/30: framer tests improvements |
---- 2016/11/04: adding lfsr sub-component test ressources |
---- 2016/11/05: adding mapper sub-component test ressources |
---- 2016/11/08: adding srrc + filter sub-components test ressources |
---- 2016/11/18: adding differential coder + symbols to samples mapper sub-components test ressources |
---- 2016/11/20: adding files output for samples to allow external software analysis |
---- 2017/15/01: adding convolutional coder |
------------------------------- |
--TODO: functions for sub-components interactions and checks (wb_read, wb_write, buffer_read, ...) |
|
-- To convert hexa ASCII encoded output files (hex) to binary files (raw wav) : xxd -r -p samples.hex > samples.wav |
-- To change endianness: xxd -r -p samples.hex | dd conv=swab of=samples.wav |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
use std.textio.all; |
library work; |
use work.ccsds_rxtx_functions.all; |
use work.ccsds_rxtx_parameters.all; |
use work.ccsds_rxtx_types.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_rxtx_bench - rx/tx unit test tool |
--============================================================================= |
entity ccsds_rxtx_bench is |
generic ( |
-- system parameters |
CCSDS_RXTX_BENCH_RXTX0_RX_PHYS_SIG_QUANT_DEPTH: integer := RX_PHYS_SIG_QUANT_DEPTH; |
CCSDS_RXTX_BENCH_RXTX0_TX_PHYS_SIG_QUANT_DEPTH: integer := TX_PHYS_SIG_QUANT_DEPTH; |
CCSDS_RXTX_BENCH_RXTX0_WB_ADDR_BUS_SIZE: integer := RXTX_SYSTEM_WB_ADDR_BUS_SIZE; |
CCSDS_RXTX_BENCH_RXTX0_WB_DATA_BUS_SIZE: integer := RXTX_SYSTEM_WB_DATA_BUS_SIZE; |
CCSDS_RXTX_BENCH_RXTX0_WB_WRITE_CYCLES_MAX: integer := 8; |
-- sub-systems parameters |
-- BUFFER |
CCSDS_RXTX_BENCH_BUFFER0_DATA_BUS_SIZE : integer := 32; |
CCSDS_RXTX_BENCH_BUFFER0_SIZE : integer := 16; |
-- CODER DIFFERENTIAL |
CCSDS_RXTX_BENCH_CODER_DIFF0_BITS_PER_CODEWORD: integer := 4; |
CCSDS_RXTX_BENCH_CODER_DIFF0_DATA_BUS_SIZE: integer := 32; |
-- CODER CONVOLUTIONAL |
--TODO: 2 TESTS / ONE STATIC WITH PREDIFINED INPUT/ OUTPUT + ONE DYNAMIC WITH RANDOM DATA |
CCSDS_RXTX_BENCH_CODER_CONV0_CONNEXION_VECTORS: std_logic_vector_array := ("1111001", "1011011"); |
CCSDS_RXTX_BENCH_CODER_CONV0_CONSTRAINT_SIZE: integer := 7; |
CCSDS_RXTX_BENCH_CODER_CONV0_DATA_BUS_SIZE: integer := 8; --255 |
CCSDS_RXTX_BENCH_CODER_CONV0_OPERATING_MODE: integer := 1; |
CCSDS_RXTX_BENCH_CODER_CONV0_OUTPUT_INVERSION: boolean_array := (false, true); |
CCSDS_RXTX_BENCH_CODER_CONV0_RATE_OUTPUT: integer := 2; |
CCSDS_RXTX_BENCH_CODER_CONV0_SEED: std_logic_vector := "000000"; |
CCSDS_RXTX_BENCH_CODER_CONV0_INPUT: std_logic_vector := "10000000"; |
CCSDS_RXTX_BENCH_CODER_CONV0_OUTPUT: std_logic_vector := "1011101001001001"; |
-- CRC |
CCSDS_RXTX_BENCH_CRC0_DATA: std_logic_vector := x"313233343536373839"; |
CCSDS_RXTX_BENCH_CRC0_INPUT_BYTES_REFLECTED: boolean := false; |
CCSDS_RXTX_BENCH_CRC0_INPUT_REFLECTED: boolean := false; |
CCSDS_RXTX_BENCH_CRC0_LENGTH: integer := 2; |
CCSDS_RXTX_BENCH_CRC0_OUTPUT_REFLECTED: boolean := false; |
CCSDS_RXTX_BENCH_CRC0_POLYNOMIAL: std_logic_vector := x"1021"; |
CCSDS_RXTX_BENCH_CRC0_POLYNOMIAL_REFLECTED: boolean := false; |
CCSDS_RXTX_BENCH_CRC0_RESULT: std_logic_vector := x"e5cc"; |
CCSDS_RXTX_BENCH_CRC0_SEED: std_logic_vector := x"ffff"; |
CCSDS_RXTX_BENCH_CRC0_XOR: std_logic_vector := x"0000"; |
-- FILTER |
CCSDS_RXTX_BENCH_FILTER0_MAPPER_DATA_BUS_SIZE: integer := 32; |
CCSDS_RXTX_BENCH_FILTER0_OFFSET_IQ: boolean := true; |
CCSDS_RXTX_BENCH_FILTER0_OVERSAMPLING_RATIO: integer := 4; |
CCSDS_RXTX_BENCH_FILTER0_ROLL_OFF: real := 0.5; |
CCSDS_RXTX_BENCH_FILTER0_SIG_QUANT_DEPTH: integer := 8; |
CCSDS_RXTX_BENCH_FILTER0_TARGET_SNR: real := 40.0; |
CCSDS_RXTX_BENCH_FILTER0_BITS_PER_SYMBOL: integer := 1; |
CCSDS_RXTX_BENCH_FILTER0_MODULATION_TYPE: integer := 1; |
-- FRAMER |
CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE: integer := 32; |
CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH: integer := 24; |
CCSDS_RXTX_BENCH_FRAMER0_FOOTER_LENGTH: integer := 2; |
CCSDS_RXTX_BENCH_FRAMER0_HEADER_LENGTH: integer := 6; |
CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO: integer := 8; |
-- LFSR |
CCSDS_RXTX_BENCH_LFSR0_RESULT: std_logic_vector := "1111111101001000000011101100000010011010"; |
CCSDS_RXTX_BENCH_LFSR0_MEMORY_SIZE: integer := 8; |
CCSDS_RXTX_BENCH_LFSR0_MODE: std_logic := '0'; |
CCSDS_RXTX_BENCH_LFSR0_POLYNOMIAL: std_logic_vector := x"A9"; |
CCSDS_RXTX_BENCH_LFSR0_SEED: std_logic_vector := x"FF"; |
-- MAPPER BITS SYMBOLS |
CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_BITS_PER_SYMBOL: integer := 2; |
CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_DATA_BUS_SIZE: integer := 32; |
CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_MODULATION_TYPE: integer := 1; |
-- MAPPER SYMBOLS SAMPLES |
CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_BITS_PER_SYMBOL: integer := 3; |
CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_QUANTIZATION_DEPTH: integer := 8; |
CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_TARGET_SNR: real := 40.0; |
-- SERDES |
CCSDS_RXTX_BENCH_SERDES0_DEPTH: integer := 32; |
-- SRRC |
CCSDS_RXTX_BENCH_SRRC0_APODIZATION_WINDOW_TYPE: integer := 1; |
CCSDS_RXTX_BENCH_SRRC0_OVERSAMPLING_RATIO: integer := 8; |
CCSDS_RXTX_BENCH_SRRC0_ROLL_OFF: real := 0.5; |
CCSDS_RXTX_BENCH_SRRC0_SIG_QUANT_DEPTH: integer := 16; |
-- simulation/test parameters |
CCSDS_RXTX_BENCH_BUFFER0_CLK_PERIOD: time := 10 ns; |
CCSDS_RXTX_BENCH_CODER_CONV0_CLK_PERIOD: time := 10 ns; |
CCSDS_RXTX_BENCH_CODER_CONV0_WORDS_NUMBER: integer := 1000; |
CCSDS_RXTX_BENCH_CODER_DIFF0_CLK_PERIOD: time := 10 ns; |
CCSDS_RXTX_BENCH_CODER_DIFF0_WORDS_NUMBER: integer := 1000; |
CCSDS_RXTX_BENCH_CRC0_CLK_PERIOD: time := 10 ns; |
CCSDS_RXTX_BENCH_CRC0_RANDOM_DATA_BUS_SIZE: integer:= 8; |
CCSDS_RXTX_BENCH_CRC0_RANDOM_CHECK_NUMBER: integer:= 25; |
CCSDS_RXTX_BENCH_FILTER0_CLK_PERIOD: time := 10 ns; |
CCSDS_RXTX_BENCH_FILTER0_SYMBOL_WORDS_NUMBER: integer := 1000; |
CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD: time := 10 ns; |
CCSDS_RXTX_BENCH_FRAMER0_FRAME_NUMBER: integer := 25; |
CCSDS_RXTX_BENCH_LFSR0_CLK_PERIOD: time := 10 ns; |
CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_CLK_PERIOD: time := 10 ns; |
CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_WORDS_NUMBER: integer := 1000; |
CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_CLK_PERIOD: time := 10 ns; |
CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_WORDS_NUMBER: integer := 1000; |
CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD: time := 20 ns; |
CCSDS_RXTX_BENCH_RXTX0_WB_TX_WRITE_CYCLE_NUMBER: integer := 5000; |
CCSDS_RXTX_BENCH_RXTX0_WB_TX_OVERFLOW: boolean := true; |
CCSDS_RXTX_BENCH_SEED: integer := 123456789; |
CCSDS_RXTX_BENCH_SERDES0_CLK_PERIOD: time := 10 ns; |
CCSDS_RXTX_BENCH_SERDES0_CYCLES_NUMBER: integer := 25; |
CCSDS_RXTX_BENCH_SRRC0_CLK_PERIOD: time := 10 ns; |
CCSDS_RXTX_BENCH_START_BUFFER_WAIT_DURATION: time := 2000 ns; |
CCSDS_RXTX_BENCH_START_CODER_CONV_WAIT_DURATION: time := 2000 ns; |
CCSDS_RXTX_BENCH_START_CODER_DIFF_WAIT_DURATION: time := 2000 ns; |
CCSDS_RXTX_BENCH_START_CRC_WAIT_DURATION: time := 2000 ns; |
CCSDS_RXTX_BENCH_START_FILTER_WAIT_DURATION: time := 2000 ns; |
CCSDS_RXTX_BENCH_START_FRAMER_WAIT_DURATION: time := 2000 ns; |
CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION: time := 2000 ns; |
CCSDS_RXTX_BENCH_START_LFSR_WAIT_DURATION: time := 2000 ns; |
CCSDS_RXTX_BENCH_START_MAPPER_BITS_SYMBOLS_WAIT_DURATION: time := 2000 ns; |
CCSDS_RXTX_BENCH_START_MAPPER_SYMBOLS_SAMPLES_WAIT_DURATION: time := 2000 ns; |
CCSDS_RXTX_BENCH_START_RESET_SIG_DURATION: time := 400 ns; |
CCSDS_RXTX_BENCH_START_SERDES_WAIT_DURATION: time := 2000 ns; |
CCSDS_RXTX_BENCH_START_SRRC_WAIT_DURATION: time := 2000 ns; |
CCSDS_RXTX_BENCH_START_WB_WAIT_DURATION: time := 1600 ns; |
CCSDS_RXTX_BENCH_OUTPUT_SIGNALS_ENABLE: boolean := true; |
CCSDS_RXTX_BENCH_OUTPUT_SIGNALS_FILES_NAME: string := "samples" |
); |
end ccsds_rxtx_bench; |
|
--============================================================================= |
-- architecture declaration / internal processing |
--============================================================================= |
architecture behaviour of ccsds_rxtx_bench is |
component ccsds_rxtx_top is |
port( |
wb_ack_o: out std_logic; |
wb_adr_i: in std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_WB_ADDR_BUS_SIZE-1 downto 0); |
wb_clk_i: in std_logic; |
wb_cyc_i: in std_logic; |
wb_dat_i: in std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_WB_DATA_BUS_SIZE-1 downto 0); |
wb_dat_o: out std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_WB_DATA_BUS_SIZE-1 downto 0); |
wb_err_o: out std_logic; |
wb_rst_i: in std_logic; |
wb_rty_o: out std_logic; |
wb_stb_i: in std_logic; |
wb_we_i: in std_logic; |
rx_clk_i: in std_logic; |
rx_sam_i_i: in std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_RX_PHYS_SIG_QUANT_DEPTH-1 downto 0); |
rx_sam_q_i: in std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_RX_PHYS_SIG_QUANT_DEPTH-1 downto 0); |
rx_ena_o: out std_logic; |
rx_irq_o: out std_logic; |
tx_clk_i: in std_logic; |
tx_dat_ser_i: in std_logic; |
tx_buf_ful_o: out std_logic; |
tx_idl_o: out std_logic; |
tx_sam_i_o: out std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_TX_PHYS_SIG_QUANT_DEPTH-1 downto 0); |
tx_sam_q_o: out std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_TX_PHYS_SIG_QUANT_DEPTH-1 downto 0); |
tx_clk_o: out std_logic; |
tx_ena_o: out std_logic |
); |
end component; |
component ccsds_rxtx_buffer is |
generic( |
CCSDS_RXTX_BUFFER_DATA_BUS_SIZE : integer; |
CCSDS_RXTX_BUFFER_SIZE : integer |
); |
port( |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_RXTX_BUFFER_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
dat_nxt_i: in std_logic; |
rst_i: in std_logic; |
buf_emp_o: out std_logic; |
buf_ful_o: out std_logic; |
dat_o: out std_logic_vector(CCSDS_RXTX_BUFFER_DATA_BUS_SIZE-1 downto 0); |
dat_val_o: out std_logic |
); |
end component; |
component ccsds_tx_coder_convolutional is |
generic( |
CCSDS_TX_CODER_CONV_CONNEXION_VECTORS: std_logic_vector_array; |
CCSDS_TX_CODER_CONV_CONSTRAINT_SIZE: integer; |
CCSDS_TX_CODER_CONV_DATA_BUS_SIZE: integer; |
CCSDS_TX_CODER_CONV_OPERATING_MODE: integer; |
CCSDS_TX_CODER_CONV_OUTPUT_INVERSION: boolean_array; |
CCSDS_TX_CODER_CONV_RATE_OUTPUT: integer; |
CCSDS_TX_CODER_CONV_SEED: std_logic_vector |
); |
port( |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_CODER_CONV_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
bus_o: out std_logic; |
dat_o: out std_logic_vector(CCSDS_TX_CODER_CONV_DATA_BUS_SIZE*CCSDS_TX_CODER_CONV_RATE_OUTPUT-1 downto 0); |
dat_val_o: out std_logic |
); |
end component; |
component ccsds_tx_coder_differential is |
generic( |
CCSDS_TX_CODER_DIFF_BITS_PER_CODEWORD: integer; |
CCSDS_TX_CODER_DIFF_DATA_BUS_SIZE: integer |
); |
port( |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_CODER_DIFF_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
dat_o: out std_logic_vector(CCSDS_TX_CODER_DIFF_DATA_BUS_SIZE-1 downto 0); |
dat_val_o: out std_logic |
); |
end component; |
component ccsds_rxtx_crc is |
generic( |
CCSDS_RXTX_CRC_DATA_LENGTH: integer; |
CCSDS_RXTX_CRC_FINAL_XOR: std_logic_vector; |
CCSDS_RXTX_CRC_INPUT_BYTES_REFLECTED: boolean; |
CCSDS_RXTX_CRC_INPUT_REFLECTED: boolean; |
CCSDS_RXTX_CRC_LENGTH: integer; |
CCSDS_RXTX_CRC_OUTPUT_REFLECTED: boolean; |
CCSDS_RXTX_CRC_POLYNOMIAL: std_logic_vector; |
CCSDS_RXTX_CRC_POLYNOMIAL_REFLECTED: boolean; |
CCSDS_RXTX_CRC_SEED: std_logic_vector |
); |
port( |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_RXTX_CRC_DATA_LENGTH*8-1 downto 0); |
nxt_i: in std_logic; |
pad_dat_i: in std_logic_vector(CCSDS_RXTX_CRC_LENGTH*8-1 downto 0); |
pad_dat_val_i: in std_logic; |
rst_i: in std_logic; |
crc_o: out std_logic_vector(CCSDS_RXTX_CRC_LENGTH*8-1 downto 0); |
dat_o: out std_logic_vector(CCSDS_RXTX_CRC_DATA_LENGTH*8-1 downto 0); |
bus_o: out std_logic; |
dat_val_o: out std_logic |
); |
end component; |
component ccsds_tx_filter is |
generic( |
CCSDS_TX_FILTER_OFFSET_IQ: boolean; |
CCSDS_TX_FILTER_OVERSAMPLING_RATIO: integer; |
CCSDS_TX_FILTER_SIG_QUANT_DEPTH: integer; |
CCSDS_TX_FILTER_MODULATION_TYPE: integer; |
CCSDS_TX_FILTER_TARGET_SNR: real; |
CCSDS_TX_FILTER_BITS_PER_SYMBOL: integer |
); |
port( |
clk_i: in std_logic; |
rst_i: in std_logic; |
sym_i_i: in std_logic_vector(CCSDS_TX_FILTER_BITS_PER_SYMBOL-1 downto 0); |
sym_q_i: in std_logic_vector(CCSDS_TX_FILTER_BITS_PER_SYMBOL-1 downto 0); |
sym_val_i: in std_logic; |
sam_i_o: out std_logic_vector(CCSDS_TX_FILTER_SIG_QUANT_DEPTH-1 downto 0); |
sam_q_o: out std_logic_vector(CCSDS_TX_FILTER_SIG_QUANT_DEPTH-1 downto 0); |
sam_val_o: out std_logic |
); |
end component; |
component ccsds_tx_framer is |
generic ( |
CCSDS_TX_FRAMER_HEADER_LENGTH: integer; |
CCSDS_TX_FRAMER_FOOTER_LENGTH: integer; |
CCSDS_TX_FRAMER_DATA_LENGTH: integer; |
CCSDS_TX_FRAMER_DATA_BUS_SIZE: integer; |
CCSDS_TX_FRAMER_PARALLELISM_MAX_RATIO: integer |
); |
port( |
clk_i: in std_logic; |
rst_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_FRAMER_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
dat_o: out std_logic_vector((CCSDS_TX_FRAMER_HEADER_LENGTH+CCSDS_TX_FRAMER_FOOTER_LENGTH+CCSDS_TX_FRAMER_DATA_LENGTH)*8-1 downto 0); |
dat_val_o: out std_logic; |
dat_nxt_o: out std_logic; |
idl_o: out std_logic |
); |
end component; |
component ccsds_rxtx_lfsr is |
generic( |
CCSDS_RXTX_LFSR_DATA_BUS_SIZE: integer; |
CCSDS_RXTX_LFSR_MEMORY_SIZE: integer; |
CCSDS_RXTX_LFSR_MODE: std_logic; |
CCSDS_RXTX_LFSR_POLYNOMIAL: std_logic_vector; |
CCSDS_RXTX_LFSR_SEED: std_logic_vector |
); |
port( |
clk_i: in std_logic; |
rst_i: in std_logic; |
dat_o: out std_logic_vector(CCSDS_RXTX_LFSR_DATA_BUS_SIZE-1 downto 0); |
dat_val_o: out std_logic |
); |
end component; |
component ccsds_tx_mapper_bits_symbols is |
generic( |
CCSDS_TX_MAPPER_DATA_BUS_SIZE: integer; |
CCSDS_TX_MAPPER_MODULATION_TYPE: integer; |
CCSDS_TX_MAPPER_BITS_PER_SYMBOL: integer |
); |
port( |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_MAPPER_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
sym_i_o: out std_logic_vector(CCSDS_TX_MAPPER_BITS_PER_SYMBOL-1 downto 0); |
sym_q_o: out std_logic_vector(CCSDS_TX_MAPPER_BITS_PER_SYMBOL-1 downto 0); |
sym_val_o: out std_logic |
); |
end component; |
component ccsds_tx_mapper_symbols_samples is |
generic( |
CCSDS_TX_MAPPER_TARGET_SNR: real; |
CCSDS_TX_MAPPER_BITS_PER_SYMBOL: integer; |
CCSDS_TX_MAPPER_QUANTIZATION_DEPTH: integer |
); |
port( |
clk_i: in std_logic; |
rst_i: in std_logic; |
sym_i: in std_logic_vector(CCSDS_TX_MAPPER_BITS_PER_SYMBOL-1 downto 0); |
sym_val_i: in std_logic; |
sam_val_o: out std_logic; |
sam_o: out std_logic_vector(CCSDS_TX_MAPPER_QUANTIZATION_DEPTH-1 downto 0) |
); |
end component; |
component ccsds_rxtx_serdes is |
generic ( |
CCSDS_RXTX_SERDES_DEPTH : integer |
); |
port( |
clk_i: in std_logic; |
dat_par_i: in std_logic_vector(CCSDS_RXTX_SERDES_DEPTH-1 downto 0); |
dat_par_val_i: in std_logic; |
dat_ser_i: in std_logic; |
dat_ser_val_i: in std_logic; |
rst_i: in std_logic; |
bus_o: out std_logic; |
dat_par_o: out std_logic_vector(CCSDS_RXTX_SERDES_DEPTH-1 downto 0); |
dat_par_val_o: out std_logic; |
dat_ser_o: out std_logic; |
dat_ser_val_o: out std_logic |
); |
end component; |
component ccsds_rxtx_srrc is |
generic( |
CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE: integer; |
CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO: integer; |
CCSDS_RXTX_SRRC_ROLL_OFF: real; |
CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH: integer |
); |
port( |
clk_i: in std_logic; |
rst_i: in std_logic; |
sam_i: in std_logic_vector(CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH-1 downto 0); |
sam_val_i: in std_logic; |
sam_o: out std_logic_vector(CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH-1 downto 0); |
sam_val_o: out std_logic |
); |
end component; |
|
-- internal constants |
constant CCSDS_RXTX_BENCH_FILTER0_MAPPER_CLK_PERIOD: time := CCSDS_RXTX_BENCH_FILTER0_CLK_PERIOD*CCSDS_RXTX_BENCH_FILTER0_OVERSAMPLING_RATIO; |
constant CCSDS_RXTX_BENCH_FILTER0_MAPPER_DATA_CLK_PERIOD: time := CCSDS_RXTX_BENCH_FILTER0_MAPPER_CLK_PERIOD * CCSDS_RXTX_BENCH_FILTER0_MAPPER_DATA_BUS_SIZE * CCSDS_RXTX_BENCH_FILTER0_MODULATION_TYPE / (CCSDS_RXTX_BENCH_FILTER0_BITS_PER_SYMBOL * 2); |
constant CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_DATA_CLK_PERIOD: time := CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_CLK_PERIOD * CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_DATA_BUS_SIZE * CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_MODULATION_TYPE / (CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_BITS_PER_SYMBOL * 2); |
constant CCSDS_RXTX_BENCH_RXTX0_TX_CLK_PERIOD: time := CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD/8; |
constant CCSDS_RXTX_BENCH_RXTX0_RX_CLK_PERIOD: time := CCSDS_RXTX_BENCH_RXTX0_TX_CLK_PERIOD; |
-- internal variables |
signal bench_ena_buffer0_random_data: std_logic := '0'; |
signal bench_ena_coder_conv0_random_data: std_logic := '0'; |
signal bench_ena_coder_diff0_random_data: std_logic := '0'; |
signal bench_ena_crc0_random_data: std_logic := '0'; |
signal bench_ena_filter0_random_data: std_logic := '0'; |
signal bench_ena_framer0_random_data: std_logic := '0'; |
signal bench_ena_mapper_bits_symbols0_random_data: std_logic := '0'; |
signal bench_ena_mapper_symbols_samples0_random_data: std_logic := '0'; |
signal bench_ena_rxtx0_random_data: std_logic := '0'; |
signal bench_ena_serdes0_random_data: std_logic := '0'; |
|
file CCSDS_RXTX_BENCH_FILTER0_OUTPUT_CSV_IQ_FILE: text open write_mode is out CCSDS_RXTX_BENCH_OUTPUT_SIGNALS_FILES_NAME & "_filter0_iq.csv"; |
file CCSDS_RXTX_BENCH_FILTER0_OUTPUT_HEX_IQ_FILE: text open write_mode is out CCSDS_RXTX_BENCH_OUTPUT_SIGNALS_FILES_NAME & "_filter0_iq.hex"; |
file CCSDS_RXTX_BENCH_FILTER0_OUTPUT_HEX_I_FILE: text open write_mode is out CCSDS_RXTX_BENCH_OUTPUT_SIGNALS_FILES_NAME & "_filter0_i.hex"; |
file CCSDS_RXTX_BENCH_FILTER0_OUTPUT_HEX_Q_FILE: text open write_mode is out CCSDS_RXTX_BENCH_OUTPUT_SIGNALS_FILES_NAME & "_filter0_q.hex"; |
file CCSDS_RXTX_BENCH_SRRC0_OUTPUT_HEX_FILE: text open write_mode is out CCSDS_RXTX_BENCH_OUTPUT_SIGNALS_FILES_NAME & "_srrc0.hex"; |
|
-- synthetic generated stimuli |
--NB: un-initialized on purposes - to allow observation of components default behaviour |
-- wishbone bus |
signal bench_sti_rxtx0_wb_clk: std_logic; |
signal bench_sti_rxtx0_wb_rst: std_logic; |
signal bench_sti_rxtx0_wb_adr: std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_WB_ADDR_BUS_SIZE-1 downto 0); |
signal bench_sti_rxtx0_wb_cyc: std_logic; |
signal bench_sti_rxtx0_wb_dat: std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_WB_DATA_BUS_SIZE-1 downto 0); |
signal bench_sti_rxtx0_wb_random_dat: std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_WB_DATA_BUS_SIZE-1 downto 0); |
signal bench_sti_rxtx0_wb_stb: std_logic; |
signal bench_sti_rxtx0_wb_we: std_logic; |
-- rx |
signal bench_sti_rxtx0_rx_clk: std_logic; |
signal bench_sti_rxtx0_rx_data_next: std_logic; |
signal bench_sti_rxtx0_rx_samples_i: std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_RX_PHYS_SIG_QUANT_DEPTH-1 downto 0); |
signal bench_sti_rxtx0_rx_samples_q: std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_RX_PHYS_SIG_QUANT_DEPTH-1 downto 0); |
-- tx |
signal bench_sti_rxtx0_tx_clk: std_logic; |
signal bench_sti_rxtx0_tx_data_ser: std_logic; |
-- buffer |
signal bench_sti_buffer0_clk: std_logic; |
signal bench_sti_buffer0_rst: std_logic; |
signal bench_sti_buffer0_next_data: std_logic; |
signal bench_sti_buffer0_data: std_logic_vector(CCSDS_RXTX_BENCH_BUFFER0_DATA_BUS_SIZE-1 downto 0); |
signal bench_sti_buffer0_data_valid: std_logic; |
-- coder convolutional |
signal bench_sti_coder_conv0_clk: std_logic; |
signal bench_sti_coder_conv0_rst: std_logic; |
signal bench_sti_coder_conv0_dat: std_logic_vector(CCSDS_RXTX_BENCH_CODER_CONV0_DATA_BUS_SIZE-1 downto 0); |
signal bench_sti_coder_conv0_dat_val: std_logic; |
-- coder differential |
signal bench_sti_coder_diff0_clk: std_logic; |
signal bench_sti_coder_diff0_rst: std_logic; |
signal bench_sti_coder_diff0_dat: std_logic_vector(CCSDS_RXTX_BENCH_CODER_DIFF0_DATA_BUS_SIZE-1 downto 0); |
signal bench_sti_coder_diff0_dat_val: std_logic; |
-- crc |
signal bench_sti_crc0_clk: std_logic; |
signal bench_sti_crc0_rst: std_logic; |
signal bench_sti_crc0_nxt: std_logic; |
signal bench_sti_crc0_data: std_logic_vector(CCSDS_RXTX_BENCH_CRC0_DATA'length-1 downto 0); |
signal bench_sti_crc0_padding_data_valid: std_logic; |
signal bench_sti_crc0_check_nxt: std_logic; |
signal bench_sti_crc0_check_data: std_logic_vector(CCSDS_RXTX_BENCH_CRC0_RANDOM_DATA_BUS_SIZE*8-1 downto 0); |
signal bench_sti_crc0_check_padding_data: std_logic_vector(CCSDS_RXTX_BENCH_CRC0_LENGTH*8-1 downto 0); |
signal bench_sti_crc0_check_padding_data_valid: std_logic; |
signal bench_sti_crc0_random_nxt: std_logic; |
signal bench_sti_crc0_random_data: std_logic_vector(CCSDS_RXTX_BENCH_CRC0_RANDOM_DATA_BUS_SIZE*8-1 downto 0); |
signal bench_sti_crc0_random_padding_data_valid: std_logic; |
-- filter |
signal bench_sti_filter0_clk: std_logic; |
signal bench_sti_filter0_rst: std_logic; |
signal bench_sti_filter0_sym_i: std_logic_vector(CCSDS_RXTX_BENCH_FILTER0_BITS_PER_SYMBOL-1 downto 0); |
signal bench_sti_filter0_sym_q: std_logic_vector(CCSDS_RXTX_BENCH_FILTER0_BITS_PER_SYMBOL-1 downto 0); |
signal bench_sti_filter0_sym_val: std_logic; |
signal bench_sti_filter0_mapper_data: std_logic_vector(CCSDS_RXTX_BENCH_FILTER0_MAPPER_DATA_BUS_SIZE-1 downto 0); |
signal bench_sti_filter0_mapper_clk: std_logic; |
signal bench_sti_filter0_mapper_dat_val: std_logic; |
-- framer |
signal bench_sti_framer0_clk: std_logic; |
signal bench_sti_framer0_rst: std_logic; |
signal bench_sti_framer0_data_valid: std_logic; |
signal bench_sti_framer0_data: std_logic_vector(CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE-1 downto 0); |
-- lfsr |
signal bench_sti_lfsr0_clk: std_logic; |
signal bench_sti_lfsr0_rst: std_logic; |
-- mapper bits symbols |
signal bench_sti_mapper_bits_symbols0_clk: std_logic; |
signal bench_sti_mapper_bits_symbols0_rst: std_logic; |
signal bench_sti_mapper_bits_symbols0_data: std_logic_vector(CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_DATA_BUS_SIZE-1 downto 0); |
signal bench_sti_mapper_bits_symbols0_dat_val: std_logic; |
-- mapper symbols samples |
signal bench_sti_mapper_symbols_samples0_clk: std_logic; |
signal bench_sti_mapper_symbols_samples0_rst: std_logic; |
signal bench_sti_mapper_symbols_samples0_sym: std_logic_vector(CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_BITS_PER_SYMBOL-1 downto 0); |
signal bench_sti_mapper_symbols_samples0_sym_val: std_logic; |
-- serdes |
signal bench_sti_serdes0_clk: std_logic; |
signal bench_sti_serdes0_rst: std_logic; |
signal bench_sti_serdes0_data_par_valid: std_logic; |
signal bench_sti_serdes0_data_par: std_logic_vector(CCSDS_RXTX_BENCH_SERDES0_DEPTH-1 downto 0); |
signal bench_sti_serdes0_data_ser_valid: std_logic; |
signal bench_sti_serdes0_data_ser: std_logic; |
-- srrc |
signal bench_sti_srrc0_clk: std_logic; |
signal bench_sti_srrc0_rst: std_logic; |
signal bench_sti_srrc0_sam: std_logic_vector(CCSDS_RXTX_BENCH_SRRC0_SIG_QUANT_DEPTH-1 downto 0); |
signal bench_sti_srrc0_sam_val: std_logic; |
-- core generated response |
-- wishbone bus |
signal bench_res_rxtx0_wb_ack: std_logic; |
signal bench_res_rxtx0_wb_dat: std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_WB_DATA_BUS_SIZE-1 downto 0); |
signal bench_res_rxtx0_wb_err: std_logic; |
signal bench_res_rxtx0_wb_rty: std_logic; |
-- rx |
signal bench_res_rxtx0_rx_ena: std_logic; |
signal bench_res_rxtx0_rx_irq: std_logic; |
-- tx |
signal bench_res_rxtx0_tx_clk: std_logic; |
signal bench_res_rxtx0_tx_buf_ful: std_logic; |
signal bench_res_rxtx0_tx_idl: std_logic; |
signal bench_res_rxtx0_tx_samples_i: std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_TX_PHYS_SIG_QUANT_DEPTH-1 downto 0); |
signal bench_res_rxtx0_tx_samples_q: std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_TX_PHYS_SIG_QUANT_DEPTH-1 downto 0); |
signal bench_res_rxtx0_tx_ena: std_logic; |
-- buffer |
signal bench_res_buffer0_buffer_empty: std_logic; |
signal bench_res_buffer0_buffer_full: std_logic; |
signal bench_res_buffer0_data: std_logic_vector(CCSDS_RXTX_BENCH_BUFFER0_DATA_BUS_SIZE-1 downto 0); |
signal bench_res_buffer0_data_valid: std_logic; |
-- coder convolutional |
signal bench_res_coder_conv0_dat: std_logic_vector(CCSDS_RXTX_BENCH_CODER_CONV0_DATA_BUS_SIZE*CCSDS_RXTX_BENCH_CODER_CONV0_RATE_OUTPUT-1 downto 0); |
signal bench_res_coder_conv0_dat_val: std_logic; |
signal bench_res_coder_conv0_bus: std_logic; |
-- coder differential |
signal bench_res_coder_diff0_dat: std_logic_vector(CCSDS_RXTX_BENCH_CODER_DIFF0_DATA_BUS_SIZE-1 downto 0); |
signal bench_res_coder_diff0_dat_val: std_logic; |
-- crc |
signal bench_res_crc0_busy: std_logic; |
signal bench_res_crc0_crc: std_logic_vector(CCSDS_RXTX_BENCH_CRC0_LENGTH*8-1 downto 0); |
signal bench_res_crc0_data: std_logic_vector(CCSDS_RXTX_BENCH_CRC0_DATA'length-1 downto 0); |
signal bench_res_crc0_data_valid: std_logic; |
signal bench_res_crc0_check_busy: std_logic; |
signal bench_res_crc0_check_crc: std_logic_vector(CCSDS_RXTX_BENCH_CRC0_LENGTH*8-1 downto 0); |
signal bench_res_crc0_check_data: std_logic_vector(CCSDS_RXTX_BENCH_CRC0_RANDOM_DATA_BUS_SIZE*8-1 downto 0); |
signal bench_res_crc0_check_data_valid: std_logic; |
signal bench_res_crc0_random_busy: std_logic; |
signal bench_res_crc0_random_crc: std_logic_vector(CCSDS_RXTX_BENCH_CRC0_LENGTH*8-1 downto 0); |
signal bench_res_crc0_random_data: std_logic_vector(CCSDS_RXTX_BENCH_CRC0_RANDOM_DATA_BUS_SIZE*8-1 downto 0); |
signal bench_res_crc0_random_data_valid: std_logic; |
-- filter |
signal bench_res_filter0_sam_i: std_logic_vector(CCSDS_RXTX_BENCH_FILTER0_SIG_QUANT_DEPTH-1 downto 0); |
signal bench_res_filter0_sam_q: std_logic_vector(CCSDS_RXTX_BENCH_FILTER0_SIG_QUANT_DEPTH-1 downto 0); |
signal bench_res_filter0_sam_val: std_logic; |
signal bench_res_filter0_srrc_sam_i: std_logic_vector(CCSDS_RXTX_BENCH_FILTER0_SIG_QUANT_DEPTH-1 downto 0); |
signal bench_res_filter0_srrc_sam_q: std_logic_vector(CCSDS_RXTX_BENCH_FILTER0_SIG_QUANT_DEPTH-1 downto 0); |
signal bench_res_filter0_srrc_sam_i_val: std_logic; |
signal bench_res_filter0_srrc_sam_q_val: std_logic; |
-- framer |
signal bench_res_framer0_data_valid: std_logic; |
signal bench_res_framer0_dat_nxt: std_logic; |
signal bench_res_framer0_idl: std_logic; |
signal bench_res_framer0_data: std_logic_vector((CCSDS_RXTX_BENCH_FRAMER0_HEADER_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_FOOTER_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH)*8-1 downto 0); |
-- lfsr |
signal bench_res_lfsr0_data_valid: std_logic; |
signal bench_res_lfsr0_data: std_logic_vector(CCSDS_RXTX_BENCH_LFSR0_RESULT'length-1 downto 0); |
-- mapper bits symbols |
signal bench_res_mapper_bits_symbols0_sym_i: std_logic_vector(CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_BITS_PER_SYMBOL-1 downto 0); |
signal bench_res_mapper_bits_symbols0_sym_q: std_logic_vector(CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_BITS_PER_SYMBOL-1 downto 0); |
signal bench_res_mapper_bits_symbols0_sym_val: std_logic; |
-- mapper symbols samples |
signal bench_res_mapper_symbols_samples0_sam: std_logic_vector(CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_QUANTIZATION_DEPTH-1 downto 0); |
signal bench_res_mapper_symbols_samples0_sam_val: std_logic; |
-- serdes |
signal bench_res_serdes0_busy: std_logic; |
signal bench_res_serdes0_data_par: std_logic_vector(CCSDS_RXTX_BENCH_SERDES0_DEPTH-1 downto 0); |
signal bench_res_serdes0_data_par_valid: std_logic; |
signal bench_res_serdes0_data_ser: std_logic; |
signal bench_res_serdes0_data_ser_valid: std_logic; |
-- srrc |
signal bench_res_srrc0_sam: std_logic_vector(CCSDS_RXTX_BENCH_SRRC0_SIG_QUANT_DEPTH-1 downto 0); |
signal bench_res_srrc0_sam_val: std_logic; |
signal bench_res_srrc1_sam: std_logic_vector(CCSDS_RXTX_BENCH_SRRC0_SIG_QUANT_DEPTH-1 downto 0); |
signal bench_res_srrc1_sam_val: std_logic; |
|
--============================================================================= |
-- architecture begin |
--============================================================================= |
begin |
-- Instance(s) of unit under test |
rxtx_000: ccsds_rxtx_top |
port map( |
wb_ack_o => bench_res_rxtx0_wb_ack, |
wb_adr_i => bench_sti_rxtx0_wb_adr, |
wb_clk_i => bench_sti_rxtx0_wb_clk, |
wb_cyc_i => bench_sti_rxtx0_wb_cyc, |
wb_dat_i => bench_sti_rxtx0_wb_dat, |
wb_dat_o => bench_res_rxtx0_wb_dat, |
wb_err_o => bench_res_rxtx0_wb_err, |
wb_rst_i => bench_sti_rxtx0_wb_rst, |
wb_rty_o => bench_res_rxtx0_wb_rty, |
wb_stb_i => bench_sti_rxtx0_wb_stb, |
wb_we_i => bench_sti_rxtx0_wb_we, |
rx_clk_i => bench_sti_rxtx0_rx_clk, |
rx_sam_i_i => bench_sti_rxtx0_rx_samples_i, |
rx_sam_q_i => bench_sti_rxtx0_rx_samples_q, |
rx_irq_o => bench_res_rxtx0_rx_irq, |
rx_ena_o => bench_res_rxtx0_rx_ena, |
tx_clk_i => bench_sti_rxtx0_tx_clk, |
tx_dat_ser_i => bench_sti_rxtx0_tx_data_ser, |
tx_sam_i_o => bench_res_rxtx0_tx_samples_i, |
tx_sam_q_o => bench_res_rxtx0_tx_samples_q, |
tx_clk_o => bench_res_rxtx0_tx_clk, |
tx_buf_ful_o => bench_res_rxtx0_tx_buf_ful, |
tx_idl_o => bench_res_rxtx0_tx_idl, |
tx_ena_o => bench_res_rxtx0_tx_ena |
); |
-- Instance(s) of sub-components under test |
buffer_000: ccsds_rxtx_buffer |
generic map( |
CCSDS_RXTX_BUFFER_DATA_BUS_SIZE => CCSDS_RXTX_BENCH_BUFFER0_DATA_BUS_SIZE, |
CCSDS_RXTX_BUFFER_SIZE => CCSDS_RXTX_BENCH_BUFFER0_SIZE |
) |
port map( |
clk_i => bench_sti_buffer0_clk, |
rst_i => bench_sti_buffer0_rst, |
dat_val_i => bench_sti_buffer0_data_valid, |
dat_i => bench_sti_buffer0_data, |
dat_val_o => bench_res_buffer0_data_valid, |
buf_emp_o => bench_res_buffer0_buffer_empty, |
buf_ful_o => bench_res_buffer0_buffer_full, |
dat_nxt_i => bench_sti_buffer0_next_data, |
dat_o => bench_res_buffer0_data |
); |
coder_convolutionial_000: ccsds_tx_coder_convolutional |
generic map( |
CCSDS_TX_CODER_CONV_CONNEXION_VECTORS => CCSDS_RXTX_BENCH_CODER_CONV0_CONNEXION_VECTORS, |
CCSDS_TX_CODER_CONV_CONSTRAINT_SIZE => CCSDS_RXTX_BENCH_CODER_CONV0_CONSTRAINT_SIZE, |
CCSDS_TX_CODER_CONV_DATA_BUS_SIZE => CCSDS_RXTX_BENCH_CODER_CONV0_DATA_BUS_SIZE, |
CCSDS_TX_CODER_CONV_OPERATING_MODE => CCSDS_RXTX_BENCH_CODER_CONV0_OPERATING_MODE, |
CCSDS_TX_CODER_CONV_OUTPUT_INVERSION => CCSDS_RXTX_BENCH_CODER_CONV0_OUTPUT_INVERSION, |
CCSDS_TX_CODER_CONV_RATE_OUTPUT => CCSDS_RXTX_BENCH_CODER_CONV0_RATE_OUTPUT, |
CCSDS_TX_CODER_CONV_SEED => CCSDS_RXTX_BENCH_CODER_CONV0_SEED |
) |
port map( |
clk_i => bench_sti_coder_conv0_clk, |
rst_i => bench_sti_coder_conv0_rst, |
dat_val_i => bench_sti_coder_conv0_dat_val, |
dat_i => bench_sti_coder_conv0_dat, |
bus_o => bench_res_coder_conv0_bus, |
dat_val_o => bench_res_coder_conv0_dat_val, |
dat_o => bench_res_coder_conv0_dat |
); |
coder_differential_000: ccsds_tx_coder_differential |
generic map( |
CCSDS_TX_CODER_DIFF_BITS_PER_CODEWORD => CCSDS_RXTX_BENCH_CODER_DIFF0_BITS_PER_CODEWORD, |
CCSDS_TX_CODER_DIFF_DATA_BUS_SIZE => CCSDS_RXTX_BENCH_CODER_DIFF0_DATA_BUS_SIZE |
) |
port map( |
clk_i => bench_sti_coder_diff0_clk, |
rst_i => bench_sti_coder_diff0_rst, |
dat_val_i => bench_sti_coder_diff0_dat_val, |
dat_i => bench_sti_coder_diff0_dat, |
dat_val_o => bench_res_coder_diff0_dat_val, |
dat_o => bench_res_coder_diff0_dat |
); |
crc_000: ccsds_rxtx_crc |
generic map( |
CCSDS_RXTX_CRC_DATA_LENGTH => CCSDS_RXTX_BENCH_CRC0_DATA'length/8, |
CCSDS_RXTX_CRC_LENGTH => CCSDS_RXTX_BENCH_CRC0_LENGTH, |
CCSDS_RXTX_CRC_POLYNOMIAL => CCSDS_RXTX_BENCH_CRC0_POLYNOMIAL, |
CCSDS_RXTX_CRC_SEED => CCSDS_RXTX_BENCH_CRC0_SEED, |
CCSDS_RXTX_CRC_INPUT_REFLECTED => CCSDS_RXTX_BENCH_CRC0_INPUT_REFLECTED, |
CCSDS_RXTX_CRC_INPUT_BYTES_REFLECTED => CCSDS_RXTX_BENCH_CRC0_INPUT_BYTES_REFLECTED, |
CCSDS_RXTX_CRC_OUTPUT_REFLECTED => CCSDS_RXTX_BENCH_CRC0_OUTPUT_REFLECTED, |
CCSDS_RXTX_CRC_POLYNOMIAL_REFLECTED => CCSDS_RXTX_BENCH_CRC0_POLYNOMIAL_REFLECTED, |
CCSDS_RXTX_CRC_FINAL_XOR => CCSDS_RXTX_BENCH_CRC0_XOR |
) |
port map( |
clk_i => bench_sti_crc0_clk, |
rst_i => bench_sti_crc0_rst, |
nxt_i => bench_sti_crc0_nxt, |
bus_o => bench_res_crc0_busy, |
dat_i => bench_sti_crc0_data, |
pad_dat_i => (others => '0'), |
pad_dat_val_i => bench_sti_crc0_padding_data_valid, |
crc_o => bench_res_crc0_crc, |
dat_o => bench_res_crc0_data, |
dat_val_o => bench_res_crc0_data_valid |
); |
crc_001: ccsds_rxtx_crc |
generic map( |
CCSDS_RXTX_CRC_DATA_LENGTH => CCSDS_RXTX_BENCH_CRC0_RANDOM_DATA_BUS_SIZE, |
CCSDS_RXTX_CRC_LENGTH => CCSDS_RXTX_BENCH_CRC0_LENGTH, |
CCSDS_RXTX_CRC_POLYNOMIAL => CCSDS_RXTX_BENCH_CRC0_POLYNOMIAL, |
CCSDS_RXTX_CRC_SEED => CCSDS_RXTX_BENCH_CRC0_SEED, |
CCSDS_RXTX_CRC_INPUT_REFLECTED => CCSDS_RXTX_BENCH_CRC0_INPUT_REFLECTED, |
CCSDS_RXTX_CRC_INPUT_BYTES_REFLECTED => CCSDS_RXTX_BENCH_CRC0_INPUT_BYTES_REFLECTED, |
CCSDS_RXTX_CRC_OUTPUT_REFLECTED => CCSDS_RXTX_BENCH_CRC0_OUTPUT_REFLECTED, |
CCSDS_RXTX_CRC_POLYNOMIAL_REFLECTED => CCSDS_RXTX_BENCH_CRC0_POLYNOMIAL_REFLECTED, |
CCSDS_RXTX_CRC_FINAL_XOR => CCSDS_RXTX_BENCH_CRC0_XOR |
) |
port map( |
clk_i => bench_sti_crc0_clk, |
rst_i => bench_sti_crc0_rst, |
nxt_i => bench_sti_crc0_random_nxt, |
bus_o => bench_res_crc0_random_busy, |
dat_i => bench_sti_crc0_random_data, |
pad_dat_i => (others => '0'), |
pad_dat_val_i => bench_sti_crc0_random_padding_data_valid, |
crc_o => bench_res_crc0_random_crc, |
dat_o => bench_res_crc0_random_data, |
dat_val_o => bench_res_crc0_random_data_valid |
); |
crc_002: ccsds_rxtx_crc |
generic map( |
CCSDS_RXTX_CRC_DATA_LENGTH => CCSDS_RXTX_BENCH_CRC0_RANDOM_DATA_BUS_SIZE, |
CCSDS_RXTX_CRC_LENGTH => CCSDS_RXTX_BENCH_CRC0_LENGTH, |
CCSDS_RXTX_CRC_POLYNOMIAL => CCSDS_RXTX_BENCH_CRC0_POLYNOMIAL, |
CCSDS_RXTX_CRC_SEED => CCSDS_RXTX_BENCH_CRC0_SEED, |
CCSDS_RXTX_CRC_INPUT_REFLECTED => CCSDS_RXTX_BENCH_CRC0_INPUT_REFLECTED, |
CCSDS_RXTX_CRC_INPUT_BYTES_REFLECTED => CCSDS_RXTX_BENCH_CRC0_INPUT_BYTES_REFLECTED, |
CCSDS_RXTX_CRC_OUTPUT_REFLECTED => CCSDS_RXTX_BENCH_CRC0_OUTPUT_REFLECTED, |
CCSDS_RXTX_CRC_POLYNOMIAL_REFLECTED => CCSDS_RXTX_BENCH_CRC0_POLYNOMIAL_REFLECTED, |
CCSDS_RXTX_CRC_FINAL_XOR => CCSDS_RXTX_BENCH_CRC0_XOR |
) |
port map( |
clk_i => bench_sti_crc0_clk, |
rst_i => bench_sti_crc0_rst, |
nxt_i => bench_sti_crc0_check_nxt, |
bus_o => bench_res_crc0_check_busy, |
dat_i => bench_sti_crc0_check_data, |
pad_dat_val_i => bench_sti_crc0_check_padding_data_valid, |
pad_dat_i => bench_sti_crc0_check_padding_data, |
crc_o => bench_res_crc0_check_crc, |
dat_o => bench_res_crc0_check_data, |
dat_val_o => bench_res_crc0_check_data_valid |
); |
filter000: ccsds_tx_filter |
generic map( |
CCSDS_TX_FILTER_OVERSAMPLING_RATIO => CCSDS_RXTX_BENCH_FILTER0_OVERSAMPLING_RATIO, |
CCSDS_TX_FILTER_OFFSET_IQ => CCSDS_RXTX_BENCH_FILTER0_OFFSET_IQ, |
CCSDS_TX_FILTER_SIG_QUANT_DEPTH => CCSDS_RXTX_BENCH_FILTER0_SIG_QUANT_DEPTH, |
CCSDS_TX_FILTER_MODULATION_TYPE => CCSDS_RXTX_BENCH_FILTER0_MODULATION_TYPE, |
CCSDS_TX_FILTER_TARGET_SNR => CCSDS_RXTX_BENCH_FILTER0_TARGET_SNR, |
CCSDS_TX_FILTER_BITS_PER_SYMBOL => CCSDS_RXTX_BENCH_FILTER0_BITS_PER_SYMBOL |
) |
port map( |
clk_i => bench_sti_filter0_clk, |
sym_i_i => bench_sti_filter0_sym_i, |
sym_q_i => bench_sti_filter0_sym_q, |
sym_val_i => bench_sti_filter0_sym_val, |
rst_i => bench_sti_filter0_rst, |
sam_val_o => bench_res_filter0_sam_val, |
sam_i_o => bench_res_filter0_sam_i, |
sam_q_o => bench_res_filter0_sam_q |
); |
framer_000: ccsds_tx_framer |
generic map ( |
CCSDS_TX_FRAMER_HEADER_LENGTH => CCSDS_RXTX_BENCH_FRAMER0_HEADER_LENGTH, |
CCSDS_TX_FRAMER_FOOTER_LENGTH => CCSDS_RXTX_BENCH_FRAMER0_FOOTER_LENGTH, |
CCSDS_TX_FRAMER_DATA_LENGTH => CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH, |
CCSDS_TX_FRAMER_DATA_BUS_SIZE => CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE, |
CCSDS_TX_FRAMER_PARALLELISM_MAX_RATIO => CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO |
) |
port map( |
clk_i => bench_sti_framer0_clk, |
rst_i => bench_sti_framer0_rst, |
dat_val_i => bench_sti_framer0_data_valid, |
dat_i => bench_sti_framer0_data, |
dat_val_o => bench_res_framer0_data_valid, |
dat_o => bench_res_framer0_data, |
dat_nxt_o => bench_res_framer0_dat_nxt, |
idl_o => bench_res_framer0_idl |
); |
lfsr_000: ccsds_rxtx_lfsr |
generic map( |
CCSDS_RXTX_LFSR_DATA_BUS_SIZE => CCSDS_RXTX_BENCH_LFSR0_RESULT'length, |
CCSDS_RXTX_LFSR_MEMORY_SIZE => CCSDS_RXTX_BENCH_LFSR0_MEMORY_SIZE, |
CCSDS_RXTX_LFSR_MODE => CCSDS_RXTX_BENCH_LFSR0_MODE, |
CCSDS_RXTX_LFSR_POLYNOMIAL => CCSDS_RXTX_BENCH_LFSR0_POLYNOMIAL, |
CCSDS_RXTX_LFSR_SEED => CCSDS_RXTX_BENCH_LFSR0_SEED |
) |
port map( |
clk_i => bench_sti_lfsr0_clk, |
rst_i => bench_sti_lfsr0_rst, |
dat_val_o => bench_res_lfsr0_data_valid, |
dat_o => bench_res_lfsr0_data |
); |
mapper_bits_symbols_000: ccsds_tx_mapper_bits_symbols |
generic map( |
CCSDS_TX_MAPPER_DATA_BUS_SIZE => CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_DATA_BUS_SIZE, |
CCSDS_TX_MAPPER_MODULATION_TYPE => CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_MODULATION_TYPE, |
CCSDS_TX_MAPPER_BITS_PER_SYMBOL => CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_BITS_PER_SYMBOL |
) |
port map( |
clk_i => bench_sti_mapper_bits_symbols0_clk, |
dat_i => bench_sti_mapper_bits_symbols0_data, |
dat_val_i => bench_sti_mapper_bits_symbols0_dat_val, |
rst_i => bench_sti_mapper_bits_symbols0_rst, |
sym_i_o => bench_res_mapper_bits_symbols0_sym_i, |
sym_q_o => bench_res_mapper_bits_symbols0_sym_q, |
sym_val_o => bench_res_mapper_bits_symbols0_sym_val |
); |
mapper_bits_symbols_001: ccsds_tx_mapper_bits_symbols |
generic map( |
CCSDS_TX_MAPPER_DATA_BUS_SIZE => CCSDS_RXTX_BENCH_FILTER0_MAPPER_DATA_BUS_SIZE, |
CCSDS_TX_MAPPER_MODULATION_TYPE => CCSDS_RXTX_BENCH_FILTER0_MODULATION_TYPE, |
CCSDS_TX_MAPPER_BITS_PER_SYMBOL => CCSDS_RXTX_BENCH_FILTER0_BITS_PER_SYMBOL |
) |
port map( |
clk_i => bench_sti_filter0_mapper_clk, |
dat_i => bench_sti_filter0_mapper_data, |
dat_val_i => bench_sti_filter0_mapper_dat_val, |
rst_i => bench_sti_filter0_rst, |
sym_i_o => bench_sti_filter0_sym_i, |
sym_q_o => bench_sti_filter0_sym_q, |
sym_val_o => bench_sti_filter0_sym_val |
); |
mapper_symbols_samples_000: ccsds_tx_mapper_symbols_samples |
generic map( |
CCSDS_TX_MAPPER_QUANTIZATION_DEPTH => CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_QUANTIZATION_DEPTH, |
CCSDS_TX_MAPPER_TARGET_SNR => CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_TARGET_SNR, |
CCSDS_TX_MAPPER_BITS_PER_SYMBOL => CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_BITS_PER_SYMBOL |
) |
port map( |
clk_i => bench_sti_mapper_symbols_samples0_clk, |
sym_i => bench_sti_mapper_symbols_samples0_sym, |
sym_val_i => bench_sti_mapper_symbols_samples0_sym_val, |
rst_i => bench_sti_mapper_symbols_samples0_rst, |
sam_o => bench_res_mapper_symbols_samples0_sam, |
sam_val_o => bench_res_mapper_symbols_samples0_sam_val |
); |
serdes_000: ccsds_rxtx_serdes |
generic map( |
CCSDS_RXTX_SERDES_DEPTH => CCSDS_RXTX_BENCH_SERDES0_DEPTH |
) |
port map( |
clk_i => bench_sti_serdes0_clk, |
dat_par_i => bench_sti_serdes0_data_par, |
dat_par_val_i => bench_sti_serdes0_data_par_valid, |
dat_ser_i => bench_sti_serdes0_data_ser, |
dat_ser_val_i => bench_sti_serdes0_data_ser_valid, |
rst_i => bench_sti_serdes0_rst, |
bus_o => bench_res_serdes0_busy, |
dat_par_o => bench_res_serdes0_data_par, |
dat_par_val_o => bench_res_serdes0_data_par_valid, |
dat_ser_o => bench_res_serdes0_data_ser, |
dat_ser_val_o => bench_res_serdes0_data_ser_valid |
); |
srrc_000: ccsds_rxtx_srrc |
generic map( |
CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE => CCSDS_RXTX_BENCH_SRRC0_APODIZATION_WINDOW_TYPE, |
CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO => CCSDS_RXTX_BENCH_SRRC0_OVERSAMPLING_RATIO, |
CCSDS_RXTX_SRRC_ROLL_OFF => CCSDS_RXTX_BENCH_SRRC0_ROLL_OFF, |
CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH => CCSDS_RXTX_BENCH_SRRC0_SIG_QUANT_DEPTH |
) |
port map( |
clk_i => bench_sti_srrc0_clk, |
sam_i => bench_sti_srrc0_sam, |
sam_val_i => bench_sti_srrc0_sam_val, |
rst_i => bench_sti_srrc0_rst, |
sam_o => bench_res_srrc0_sam, |
sam_val_o => bench_res_srrc0_sam_val |
); |
srrc_001: ccsds_rxtx_srrc |
generic map( |
CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE => CCSDS_RXTX_BENCH_SRRC0_APODIZATION_WINDOW_TYPE, |
CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO => CCSDS_RXTX_BENCH_SRRC0_OVERSAMPLING_RATIO, |
CCSDS_RXTX_SRRC_ROLL_OFF => CCSDS_RXTX_BENCH_SRRC0_ROLL_OFF, |
CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH => CCSDS_RXTX_BENCH_SRRC0_SIG_QUANT_DEPTH |
) |
port map( |
clk_i => bench_sti_srrc0_clk, |
sam_i => bench_res_srrc0_sam, |
sam_val_i => bench_res_srrc0_sam_val, |
rst_i => bench_sti_srrc0_rst, |
sam_o => bench_res_srrc1_sam, |
sam_val_o => bench_res_srrc1_sam_val |
); |
srrc_002: ccsds_rxtx_srrc |
generic map( |
CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE => 1, |
CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO => CCSDS_RXTX_BENCH_FILTER0_OVERSAMPLING_RATIO, |
CCSDS_RXTX_SRRC_ROLL_OFF => CCSDS_RXTX_BENCH_FILTER0_ROLL_OFF, |
CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH => CCSDS_RXTX_BENCH_FILTER0_SIG_QUANT_DEPTH |
) |
port map( |
clk_i => bench_sti_filter0_clk, |
sam_i => bench_res_filter0_sam_i, |
sam_val_i => bench_res_filter0_sam_val, |
rst_i => bench_sti_filter0_rst, |
sam_o => bench_res_filter0_srrc_sam_i, |
sam_val_o => bench_res_filter0_srrc_sam_i_val |
); |
srrc_003: ccsds_rxtx_srrc |
generic map( |
CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE => 1, |
CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO => CCSDS_RXTX_BENCH_FILTER0_OVERSAMPLING_RATIO, |
CCSDS_RXTX_SRRC_ROLL_OFF => CCSDS_RXTX_BENCH_FILTER0_ROLL_OFF, |
CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH => CCSDS_RXTX_BENCH_FILTER0_SIG_QUANT_DEPTH |
) |
port map( |
clk_i => bench_sti_filter0_clk, |
sam_i => bench_res_filter0_sam_q, |
sam_val_i => bench_res_filter0_sam_val, |
rst_i => bench_sti_filter0_rst, |
sam_o => bench_res_filter0_srrc_sam_q, |
sam_val_o => bench_res_filter0_srrc_sam_q_val |
); |
--============================================================================= |
-- Begin of bench_sti_rxtx0_wb_clkp |
-- bench_sti_rxtx0_wb_clk generation |
--============================================================================= |
-- read: |
-- write: bench_sti_rxtx0_wb_clk |
-- r/w: |
BENCH_STI_RXTX0_WB_CLKP : process |
begin |
bench_sti_rxtx0_wb_clk <= '1'; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD/2; |
bench_sti_rxtx0_wb_clk <= '0'; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD/2; |
end process; |
--============================================================================= |
-- Begin of bench_sti_rxtx0_rx_clkp |
-- bench_sti_rxtx0_rx_clk generation |
--============================================================================= |
-- read: |
-- write: bench_sti_rxtx0_rx_clk |
-- r/w: |
BENCH_STI_RXTX0_RX_CLKP : process |
begin |
bench_sti_rxtx0_rx_clk <= '1'; |
wait for CCSDS_RXTX_BENCH_RXTX0_RX_CLK_PERIOD/2; |
bench_sti_rxtx0_rx_clk <= '0'; |
wait for CCSDS_RXTX_BENCH_RXTX0_RX_CLK_PERIOD/2; |
end process; |
--============================================================================= |
-- Begin of bench_sti_rxtx0_tx_clkp |
-- bench_sti_rxtx0_tx_clk generation |
--============================================================================= |
-- read: |
-- write: bench_sti_rxtx0_tx_clk |
-- r/w: |
BENCH_STI_RXTX0_TX_CLKP : process |
begin |
bench_sti_rxtx0_tx_clk <= '1'; |
wait for CCSDS_RXTX_BENCH_RXTX0_TX_CLK_PERIOD/2; |
bench_sti_rxtx0_tx_clk <= '0'; |
wait for CCSDS_RXTX_BENCH_RXTX0_TX_CLK_PERIOD/2; |
end process; |
--============================================================================= |
-- Begin of bench_sti_buffer0_clkp |
-- bench_sti_buffer0_clk generation |
--============================================================================= |
-- read: |
-- write: bench_sti_buffer0_clk |
-- r/w: |
BENCH_STI_BUFFER0_CLKP : process |
begin |
bench_sti_buffer0_clk <= '1'; |
wait for CCSDS_RXTX_BENCH_BUFFER0_CLK_PERIOD/2; |
bench_sti_buffer0_clk <= '0'; |
wait for CCSDS_RXTX_BENCH_BUFFER0_CLK_PERIOD/2; |
end process; |
--============================================================================= |
-- Begin of bench_sti_coder_conv0_clk |
-- bench_sti_coder_conv0_clk generation |
--============================================================================= |
-- read: |
-- write: bench_sti_coder_conv0_clk |
-- r/w: |
BENCH_STI_CODER_CONV0_CLKP : process |
begin |
bench_sti_coder_conv0_clk <= '1'; |
wait for CCSDS_RXTX_BENCH_CODER_CONV0_CLK_PERIOD/2; |
bench_sti_coder_conv0_clk <= '0'; |
wait for CCSDS_RXTX_BENCH_CODER_CONV0_CLK_PERIOD/2; |
end process; |
--============================================================================= |
-- Begin of bench_sti_coder_diff0_clk |
-- bench_sti_coder_diff0_clk generation |
--============================================================================= |
-- read: |
-- write: bench_sti_coder_diff0_clk |
-- r/w: |
BENCH_STI_CODER_DIFF0_CLKP : process |
begin |
bench_sti_coder_diff0_clk <= '1'; |
wait for CCSDS_RXTX_BENCH_CODER_DIFF0_CLK_PERIOD/2; |
bench_sti_coder_diff0_clk <= '0'; |
wait for CCSDS_RXTX_BENCH_CODER_DIFF0_CLK_PERIOD/2; |
end process; |
--============================================================================= |
-- Begin of bench_sti_crc0_clkp |
-- bench_sti_crc0_clk generation |
--============================================================================= |
-- read: |
-- write: bench_sti_crc0_clk |
-- r/w: |
BENCH_STI_CRC0_CLKP : process |
begin |
bench_sti_crc0_clk <= '1'; |
wait for CCSDS_RXTX_BENCH_CRC0_CLK_PERIOD/2; |
bench_sti_crc0_clk <= '0'; |
wait for CCSDS_RXTX_BENCH_CRC0_CLK_PERIOD/2; |
end process; |
--============================================================================= |
-- Begin of bench_sti_filter0_clkp |
-- bench_sti_filter0_clk generation |
--============================================================================= |
-- read: |
-- write: bench_sti_filter0_clk |
-- r/w: |
BENCH_STI_FILTER0_CLKP : process |
begin |
bench_sti_filter0_clk <= '1'; |
wait for CCSDS_RXTX_BENCH_FILTER0_CLK_PERIOD/2; |
bench_sti_filter0_clk <= '0'; |
wait for CCSDS_RXTX_BENCH_FILTER0_CLK_PERIOD/2; |
end process; |
--============================================================================= |
-- Begin of bench_sti_filter0_mapper_clkp |
-- bench_sti_filter0_mapper_clk generation |
--============================================================================= |
-- read: |
-- write: bench_sti_filter0_mapper_clk |
-- r/w: |
BENCH_STI_FILTER0_MAPPER_CLKP : process |
begin |
bench_sti_filter0_mapper_clk <= '1'; |
wait for CCSDS_RXTX_BENCH_FILTER0_MAPPER_CLK_PERIOD/2; |
bench_sti_filter0_mapper_clk <= '0'; |
wait for CCSDS_RXTX_BENCH_FILTER0_MAPPER_CLK_PERIOD/2; |
end process; |
--============================================================================= |
-- Begin of bench_sti_framer0_clkp |
-- bench_sti_framer0_clk generation |
--============================================================================= |
-- read: |
-- write: bench_sti_framer0_clk |
-- r/w: |
BENCH_STI_FRAMER0_CLKP : process |
begin |
bench_sti_framer0_clk <= '1'; |
wait for CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD/2; |
bench_sti_framer0_clk <= '0'; |
wait for CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD/2; |
end process; |
--============================================================================= |
-- Begin of bench_sti_lfsr0_clkp |
-- bench_sti_lfsr0_clk generation |
--============================================================================= |
-- read: |
-- write: bench_sti_lfsr0_clk |
-- r/w: |
BENCH_STI_LFSR0_CLKP : process |
begin |
bench_sti_lfsr0_clk <= '1'; |
wait for CCSDS_RXTX_BENCH_LFSR0_CLK_PERIOD/2; |
bench_sti_lfsr0_clk <= '0'; |
wait for CCSDS_RXTX_BENCH_LFSR0_CLK_PERIOD/2; |
end process; |
--============================================================================= |
-- Begin of bench_sti_mapper_bits_symbols0_clkp |
-- bench_sti_mapper_bits_symbols0_clk generation |
--============================================================================= |
-- read: |
-- write: bench_sti_mapper_bits_symbols0_clk |
-- r/w: |
BENCH_STI_MAPPER_BITS_SYMBOLS0_CLKP : process |
begin |
bench_sti_mapper_bits_symbols0_clk <= '1'; |
wait for CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_CLK_PERIOD/2; |
bench_sti_mapper_bits_symbols0_clk <= '0'; |
wait for CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_CLK_PERIOD/2; |
end process; |
--============================================================================= |
-- Begin of bench_sti_mapper_symbols_samples0_clkp |
-- bench_sti_mapper_symbols_samples0_clk generation |
--============================================================================= |
-- read: |
-- write: bench_sti_mapper_symbols_samples0_clk |
-- r/w: |
BENCH_STI_MAPPER_SYMBOLS_SAMPLES0_CLKP : process |
begin |
bench_sti_mapper_symbols_samples0_clk <= '1'; |
wait for CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_CLK_PERIOD/2; |
bench_sti_mapper_symbols_samples0_clk <= '0'; |
wait for CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_CLK_PERIOD/2; |
end process; |
--============================================================================= |
-- Begin of bench_sti_serdes0_clkp |
-- bench_sti_serdes0_clk generation |
--============================================================================= |
-- read: |
-- write: bench_sti_serdes0_clk |
-- r/w: |
BENCH_STI_SERDES0_CLKP : process |
begin |
bench_sti_serdes0_clk <= '1'; |
wait for CCSDS_RXTX_BENCH_SERDES0_CLK_PERIOD/2; |
bench_sti_serdes0_clk <= '0'; |
wait for CCSDS_RXTX_BENCH_SERDES0_CLK_PERIOD/2; |
end process; |
--============================================================================= |
-- Begin of bench_sti_srrc0_clkp |
-- bench_sti_srrc0_clk generation |
--============================================================================= |
-- read: |
-- write: bench_sti_srrc0_clk |
-- r/w: |
BENCH_STI_SRRC0_CLKP : process |
begin |
bench_sti_srrc0_clk <= '1'; |
wait for CCSDS_RXTX_BENCH_SRRC0_CLK_PERIOD/2; |
bench_sti_srrc0_clk <= '0'; |
wait for CCSDS_RXTX_BENCH_SRRC0_CLK_PERIOD/2; |
end process; |
--============================================================================= |
-- Begin of bench_sti_rxtx0_tx_datap |
-- bench_sti_rxtx0_tx_data generation / dephased from 1/2 clk with bench_sti_rxtx0_tx_clk |
--============================================================================= |
-- read: |
-- write: bench_sti_rxtx0_tx_data_ser0 |
-- r/w: |
BENCH_STI_RXTX0_TX_DATAP : process |
variable seed1 : positive := CCSDS_RXTX_BENCH_SEED; |
variable seed2 : positive := CCSDS_RXTX_BENCH_SEED*2; |
variable random : std_logic_vector(1 downto 0); |
begin |
if (bench_ena_rxtx0_random_data = '1') then |
sim_generate_random_std_logic_vector(2,seed1,seed2,random); |
bench_sti_rxtx0_tx_data_ser <= random(0); |
end if; |
wait for CCSDS_RXTX_BENCH_RXTX0_TX_CLK_PERIOD; |
end process; |
--============================================================================= |
-- Begin of bench_sti_buffer0_datap |
-- bench_sti_buffer0_data generation |
--============================================================================= |
-- read: bench_ena_buffer0_random_data |
-- write: bench_sti_buffer0_data |
-- r/w: |
BENCH_STI_BUFFER0_DATAP : process |
variable seed1 : positive := CCSDS_RXTX_BENCH_SEED; |
variable seed2 : positive := CCSDS_RXTX_BENCH_SEED*2; |
variable random : std_logic_vector(CCSDS_RXTX_BENCH_BUFFER0_DATA_BUS_SIZE-1 downto 0); |
begin |
if (bench_ena_buffer0_random_data = '1') then |
sim_generate_random_std_logic_vector(CCSDS_RXTX_BENCH_BUFFER0_DATA_BUS_SIZE,seed1,seed2,random); |
bench_sti_buffer0_data <= random; |
end if; |
wait for CCSDS_RXTX_BENCH_BUFFER0_CLK_PERIOD; |
end process; |
--============================================================================= |
-- Begin of bench_sti_coder_conv0_datap |
-- bench_sti_coder_conv0_random_data generation |
--============================================================================= |
-- read: bench_ena_coder_conv0_random_data |
-- write: bench_sti_coder_conv0_dat |
-- r/w: |
BENCH_STI_CODER_CONV0_DATAP : process |
variable seed1 : positive := CCSDS_RXTX_BENCH_SEED; |
variable seed2 : positive := CCSDS_RXTX_BENCH_SEED*2; |
variable random : std_logic_vector(CCSDS_RXTX_BENCH_CODER_CONV0_DATA_BUS_SIZE-1 downto 0); |
begin |
-- if (bench_ena_coder_conv0_random_data = '1') then |
-- sim_generate_random_std_logic_vector(CCSDS_RXTX_BENCH_CODER_CONV0_DATA_BUS_SIZE,seed1,seed2,random); |
-- bench_sti_coder_conv0_dat <= random; |
-- end if; |
-- wait for CCSDS_RXTX_BENCH_CODER_CONV0_CLK_PERIOD; |
bench_sti_coder_conv0_dat <= CCSDS_RXTX_BENCH_CODER_CONV0_INPUT; |
wait; |
end process; |
--============================================================================= |
-- Begin of bench_sti_coder_diff0_datap |
-- bench_sti_coder_diff0_random_data generation |
--============================================================================= |
-- read: bench_ena_coder_diff0_random_data |
-- write: bench_sti_coder_diff0_dat |
-- r/w: |
BENCH_STI_CODER_DIFF0_DATAP : process |
variable seed1 : positive := CCSDS_RXTX_BENCH_SEED; |
variable seed2 : positive := CCSDS_RXTX_BENCH_SEED*2; |
variable random : std_logic_vector(CCSDS_RXTX_BENCH_CODER_DIFF0_DATA_BUS_SIZE-1 downto 0); |
begin |
if (bench_ena_coder_diff0_random_data = '1') then |
sim_generate_random_std_logic_vector(CCSDS_RXTX_BENCH_CODER_DIFF0_DATA_BUS_SIZE,seed1,seed2,random); |
bench_sti_coder_diff0_dat <= random; |
end if; |
wait for CCSDS_RXTX_BENCH_CODER_DIFF0_CLK_PERIOD; |
end process; |
--============================================================================= |
-- Begin of bench_sti_crc0_datap |
-- bench_sti_crc0_random_data generation |
--============================================================================= |
-- read: bench_ena_crc0_random_data |
-- write: bench_sti_crc0_random_data |
-- r/w: |
BENCH_STI_CRC0_DATAP : process |
variable seed1 : positive := CCSDS_RXTX_BENCH_SEED; |
variable seed2 : positive := CCSDS_RXTX_BENCH_SEED*2; |
variable random : std_logic_vector(CCSDS_RXTX_BENCH_CRC0_RANDOM_DATA_BUS_SIZE*8-1 downto 0); |
begin |
if (bench_ena_crc0_random_data = '1') then |
sim_generate_random_std_logic_vector(CCSDS_RXTX_BENCH_CRC0_RANDOM_DATA_BUS_SIZE*8,seed1,seed2,random); |
bench_sti_crc0_random_data <= random; |
end if; |
wait for CCSDS_RXTX_BENCH_CRC0_CLK_PERIOD; |
end process; |
--============================================================================= |
-- Begin of bench_sti_filter0_datap |
-- bench_sti_filter0_mapper_data generation |
--============================================================================= |
-- read: bench_ena_filter0_random_data |
-- write: bench_sti_filter0_mapper_data |
-- r/w: |
BENCH_STI_FILTER0_DATAP : process |
variable seed1 : positive := CCSDS_RXTX_BENCH_SEED; |
variable seed2 : positive := CCSDS_RXTX_BENCH_SEED*2; |
variable random : std_logic_vector(CCSDS_RXTX_BENCH_FILTER0_MAPPER_DATA_BUS_SIZE-1 downto 0); |
begin |
if (bench_ena_filter0_random_data = '1') then |
sim_generate_random_std_logic_vector(CCSDS_RXTX_BENCH_FILTER0_MAPPER_DATA_BUS_SIZE,seed1,seed2,random); |
bench_sti_filter0_mapper_data <= random; |
end if; |
wait for CCSDS_RXTX_BENCH_FILTER0_MAPPER_DATA_CLK_PERIOD; |
end process; |
--============================================================================= |
-- Begin of bench_sti_framer0_datap |
-- bench_sti_framer0_data generation |
--============================================================================= |
-- read: bench_ena_framer0_random_data |
-- write: bench_sti_framer0_data |
-- r/w: |
BENCH_STI_FRAMER0_DATAP : process |
variable seed1 : positive := CCSDS_RXTX_BENCH_SEED; |
variable seed2 : positive := CCSDS_RXTX_BENCH_SEED*2; |
variable random : std_logic_vector(CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE-1 downto 0); |
begin |
if (bench_ena_framer0_random_data = '1') then |
sim_generate_random_std_logic_vector(CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE,seed1,seed2,random); |
bench_sti_framer0_data <= random; |
end if; |
wait for CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD; |
end process; |
--============================================================================= |
-- Begin of bench_sti_mapper_bits_symbols0_datap |
-- bench_sti_mapper_bits_symbols0_data generation |
--============================================================================= |
-- read: bench_ena_mapper_bits_symbols0_random_data |
-- write: bench_sti_mapper_bits_symbols0_data |
-- r/w: |
BENCH_STI_MAPPER_BITS_SYMBOLS0_DATAP : process |
variable seed1 : positive := CCSDS_RXTX_BENCH_SEED; |
variable seed2 : positive := CCSDS_RXTX_BENCH_SEED*2; |
variable random : std_logic_vector(CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_DATA_BUS_SIZE-1 downto 0); |
begin |
if (bench_ena_mapper_bits_symbols0_random_data = '1') then |
sim_generate_random_std_logic_vector(CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_DATA_BUS_SIZE,seed1,seed2,random); |
bench_sti_mapper_bits_symbols0_data <= random; |
end if; |
wait for CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_DATA_CLK_PERIOD; |
end process; |
--============================================================================= |
-- Begin of bench_sti_mapper_symbols_samples0_datap |
-- bench_sti_mapper_symbols_samples0_data generation |
--============================================================================= |
-- read: bench_ena_mapper_symbols_samples0_random_data |
-- write: bench_sti_mapper_symbols_samples0_data |
-- r/w: |
BENCH_STI_MAPPER_SYMBOLS_SAMPLES0_DATAP : process |
variable seed1 : positive := CCSDS_RXTX_BENCH_SEED; |
variable seed2 : positive := CCSDS_RXTX_BENCH_SEED*2; |
variable random : std_logic_vector(CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_BITS_PER_SYMBOL-1 downto 0); |
begin |
if (bench_ena_mapper_symbols_samples0_random_data = '1') then |
sim_generate_random_std_logic_vector(CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_BITS_PER_SYMBOL,seed1,seed2,random); |
bench_sti_mapper_symbols_samples0_sym <= random; |
end if; |
wait for CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_CLK_PERIOD; |
end process; |
--============================================================================= |
-- Begin of bench_sti_serdes0_datap |
-- bench_sti_serdes0_data generation |
--============================================================================= |
-- read: bench_ena_serdes0_random_data |
-- write: bench_sti_serdes0_data_par, bench_sti_serdes0_data_ser |
-- r/w: |
BENCH_STI_SERDES0_DATAP : process |
variable seed1 : positive := CCSDS_RXTX_BENCH_SEED; |
variable seed2 : positive := CCSDS_RXTX_BENCH_SEED*2; |
variable random : std_logic_vector(CCSDS_RXTX_BENCH_SERDES0_DEPTH-1 downto 0); |
begin |
if (bench_ena_serdes0_random_data = '1') then |
sim_generate_random_std_logic_vector(CCSDS_RXTX_BENCH_SERDES0_DEPTH,seed1,seed2,random); |
bench_sti_serdes0_data_par <= random; |
bench_sti_serdes0_data_ser <= random(0); |
end if; |
wait for CCSDS_RXTX_BENCH_SERDES0_CLK_PERIOD; |
end process; |
--============================================================================= |
-- Begin of bench_sti_rxtx0_rx_samplesp |
-- bench_sti_rxtx0_rx_samples generation |
--============================================================================= |
-- read: bench_ena_rxtx0_random_data |
-- write: bench_sti_rxtx0_rx_samples_i, bench_sti_rxtx0_rx_samples_q |
-- r/w: |
BENCH_STI_RXTX0_RX_SAMPLESP : process |
variable seed1 : positive := CCSDS_RXTX_BENCH_SEED; |
variable seed2 : positive := CCSDS_RXTX_BENCH_SEED*2; |
variable random1 : std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_RX_PHYS_SIG_QUANT_DEPTH-1 downto 0); |
variable random2 : std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_RX_PHYS_SIG_QUANT_DEPTH-1 downto 0); |
begin |
if (bench_ena_rxtx0_random_data = '1') then |
sim_generate_random_std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_RX_PHYS_SIG_QUANT_DEPTH,seed1,seed2,random1); |
sim_generate_random_std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_RX_PHYS_SIG_QUANT_DEPTH,seed2,seed1,random2); |
bench_sti_rxtx0_rx_samples_i <= random1; |
bench_sti_rxtx0_rx_samples_q <= random2; |
end if; |
wait for CCSDS_RXTX_BENCH_RXTX0_RX_CLK_PERIOD; |
end process; |
--============================================================================= |
-- Begin of bench_sti_rxtx0_wb_datap |
-- bench_sti_rxtx0_wb_random_dat generation |
--============================================================================= |
-- read: bench_ena_rxtx0_random_data |
-- write: bench_sti_rxtx0_wb_random_dat0 |
-- r/w: |
BENCH_STI_RXTX0_WB_DATP : process |
variable seed1 : positive := CCSDS_RXTX_BENCH_SEED; |
variable seed2 : positive := CCSDS_RXTX_BENCH_SEED*2; |
variable random1 : std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_WB_DATA_BUS_SIZE-1 downto 0); |
begin |
if (bench_ena_rxtx0_random_data = '1') then |
sim_generate_random_std_logic_vector(CCSDS_RXTX_BENCH_RXTX0_WB_DATA_BUS_SIZE,seed1,seed2,random1); |
bench_sti_rxtx0_wb_random_dat <= random1; |
end if; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
end process; |
--============================================================================= |
-- Begin of bufferrwp |
-- generation of buffer subsystem read-write unit-tests |
--============================================================================= |
-- read: bench_res_buffer0_buffer_empty, bench_res_buffer0_buffer_full, bench_res_buffer0_data, bench_res_buffer0_data_valid |
-- write: bench_sti_buffer0_data_valid, bench_sti_buffer0_next_data, bench_ena_buffer0_random_data |
-- r/w: |
BUFFERRWP : process |
type buffer_array is array (CCSDS_RXTX_BENCH_BUFFER0_SIZE downto 0) of std_logic_vector(CCSDS_RXTX_BENCH_BUFFER0_DATA_BUS_SIZE-1 downto 0); |
variable buffer_expected_stored_data: buffer_array := (others => (others => '0')); |
variable buffer_content_ok: std_logic := '1'; |
begin |
-- let the system free run |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2); |
-- default state tests: |
-- check buffer is empty |
if (bench_res_buffer0_buffer_empty = '1') then |
report "BUFFERRWP: OK - Default state - Buffer is empty" severity note; |
else |
report "BUFFERRWP: KO - Default state - Buffer is not empty" severity warning; |
end if; |
-- check buffer is not full |
if (bench_res_buffer0_buffer_full = '0')then |
report "BUFFERRWP: OK - Default state - Buffer is not full" severity note; |
else |
report "BUFFERRWP: KO - Default state - Buffer is full" severity warning; |
end if; |
-- let the system reset |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2 + CCSDS_RXTX_BENCH_START_RESET_SIG_DURATION + CCSDS_RXTX_BENCH_START_BUFFER_WAIT_DURATION); |
-- initial state tests: |
-- check buffer is empty |
if (bench_res_buffer0_buffer_empty = '1') then |
report "BUFFERRWP: OK - Initial state - Buffer is empty" severity note; |
else |
report "BUFFERRWP: KO - Initial state - Buffer is not empty" severity warning; |
end if; |
-- check buffer is not full |
if (bench_res_buffer0_buffer_full = '0')then |
report "BUFFERRWP: OK - Initial state - Buffer is not full" severity note; |
else |
report "BUFFERRWP: KO - Initial state - Buffer is full" severity warning; |
end if; |
-- behaviour tests: |
report "BUFFERRWP: START BUFFER READ-WRITE TESTS" severity note; |
-- ask for data |
bench_sti_buffer0_next_data <= '1'; |
wait for CCSDS_RXTX_BENCH_BUFFER0_CLK_PERIOD; |
if (bench_res_buffer0_data_valid = '0') then |
report "BUFFERRWP: OK - No data came out with an empty buffer" severity note; |
else |
report "BUFFERRWP: KO - Data came out - buffer is empty / incoherent" severity warning; |
end if; |
bench_sti_buffer0_next_data <= '0'; |
bench_ena_buffer0_random_data <= '1'; |
wait for CCSDS_RXTX_BENCH_BUFFER0_CLK_PERIOD; |
-- store data |
bench_sti_buffer0_data_valid <= '1'; |
wait for CCSDS_RXTX_BENCH_BUFFER0_CLK_PERIOD/2; |
buffer_expected_stored_data(0) := bench_sti_buffer0_data; |
wait for CCSDS_RXTX_BENCH_BUFFER0_CLK_PERIOD/2; |
bench_sti_buffer0_data_valid <= '0'; |
wait for CCSDS_RXTX_BENCH_BUFFER0_CLK_PERIOD; |
if (bench_res_buffer0_buffer_empty = '0') then |
report "BUFFERRWP: OK - Buffer is not empty" severity note; |
else |
report "BUFFERRWP: KO - Buffer should not be empty" severity warning; |
end if; |
wait for CCSDS_RXTX_BENCH_BUFFER0_CLK_PERIOD; |
-- get data |
bench_sti_buffer0_next_data <= '1'; |
wait for CCSDS_RXTX_BENCH_BUFFER0_CLK_PERIOD; |
bench_sti_buffer0_next_data <= '0'; |
if (bench_res_buffer0_data_valid = '1') then |
report "BUFFERRWP: OK - Data valid signal received" severity note; |
else |
report "BUFFERRWP: KO - Data valid signal not received" severity warning; |
end if; |
if (bench_res_buffer0_data = buffer_expected_stored_data(0)) then |
report "BUFFERRWP: OK - Received value is equal to previously stored value" severity note; |
else |
report "BUFFERRWP: KO - Received value is different from previously stored value" severity warning; |
report "Received value:" severity note; |
for i in 0 to bench_res_buffer0_data'length-1 loop |
report std_logic'image(bench_res_buffer0_data(i)); |
end loop; |
report "Expected value:" severity note; |
for i in 0 to buffer_expected_stored_data(0)'length-1 loop |
report std_logic'image(buffer_expected_stored_data(0)(i)); |
end loop; |
end if; |
wait for CCSDS_RXTX_BENCH_BUFFER0_CLK_PERIOD; |
if (bench_res_buffer0_buffer_empty = '1') then |
report "BUFFERRWP: OK - Buffer is empty after reading value" severity note; |
else |
report "BUFFERRWP: KO - Buffer is not empty" severity warning; |
end if; |
wait for CCSDS_RXTX_BENCH_BUFFER0_CLK_PERIOD; |
-- store lot of data / make the buffer full |
bench_sti_buffer0_data_valid <= '1'; |
for i in 0 to CCSDS_RXTX_BENCH_BUFFER0_SIZE loop |
wait for CCSDS_RXTX_BENCH_BUFFER0_CLK_PERIOD/2; |
buffer_expected_stored_data(i) := bench_sti_buffer0_data; |
wait for CCSDS_RXTX_BENCH_BUFFER0_CLK_PERIOD/2; |
if (bench_res_buffer0_buffer_full = '1') then |
if (i < CCSDS_RXTX_BENCH_BUFFER0_SIZE) then |
report "BUFFERRWP: KO - Buffer is full too early - loop: " & integer'image(i) & " value of the buffer array" severity warning; |
else |
report "BUFFERRWP: OK - Buffer is full after all write operations" severity note; |
end if; |
else |
if (i = CCSDS_RXTX_BENCH_BUFFER0_SIZE) then |
report "BUFFERRWP: KO - Buffer is not full after all write operations" severity note; |
end if; |
end if; |
end loop; |
bench_sti_buffer0_data_valid <= '0'; |
wait for CCSDS_RXTX_BENCH_BUFFER0_CLK_PERIOD; |
bench_ena_buffer0_random_data <= '0'; |
-- read all data / make the buffer empty |
bench_sti_buffer0_next_data <= '1'; |
for i in 0 to CCSDS_RXTX_BENCH_BUFFER0_SIZE loop |
wait for CCSDS_RXTX_BENCH_BUFFER0_CLK_PERIOD; |
if (buffer_expected_stored_data(i) /= bench_res_buffer0_data) then |
if (i < CCSDS_RXTX_BENCH_BUFFER0_SIZE) then |
report "BUFFERRWP: KO - Received value is different from previously stored value - loop: " & integer'image(i) severity warning; |
buffer_content_ok := '0'; |
end if; |
end if; |
if (i = CCSDS_RXTX_BENCH_BUFFER0_SIZE) and (buffer_content_ok = '1') then |
report "BUFFERRWP: OK - Received values are all equal to previously stored values" severity note; |
end if; |
if (bench_res_buffer0_data_valid = '0') then |
if (i < CCSDS_RXTX_BENCH_BUFFER0_SIZE) then |
report "BUFFERRWP: KO - Data valid signal not received - loop: " & integer'image(i) severity warning; |
end if; |
end if; |
if (bench_res_buffer0_buffer_empty = '1') then |
if (i < CCSDS_RXTX_BENCH_BUFFER0_SIZE) then |
report "BUFFERRWP: KO - Data empty signal received too early - loop: " & integer'image(i) severity warning; |
else |
report "BUFFERRWP: OK - Buffer is empty after all read operations" severity note; |
end if; |
else |
if (i = CCSDS_RXTX_BENCH_BUFFER0_SIZE) then |
report "BUFFERRWP: KO - Buffer is not empty after all read operations" severity warning; |
end if; |
end if; |
end loop; |
bench_sti_buffer0_next_data <= '0'; |
-- final state tests: |
-- check buffer is empty |
if (bench_res_buffer0_buffer_empty = '1') then |
report "BUFFERRWP: OK - Final state - Buffer is empty" severity note; |
else |
report "BUFFERRWP: KO - Final state - Buffer is not empty" severity warning; |
end if; |
-- check buffer is not full |
if (bench_res_buffer0_buffer_full = '0')then |
report "BUFFERRWP: OK - Final state - Buffer is not full" severity note; |
else |
report "BUFFERRWP: KO - Final state - Buffer is full" severity warning; |
end if; |
report "BUFFERRWP: END BUFFER READ-WRITE TESTS" severity note; |
-- do nothing |
wait; |
end process; |
--============================================================================= |
-- Begin of coderconvp |
-- generation of coder convolutional subsystem unit-tests |
--============================================================================= |
-- read: bench_res_coder_conv0_dat, bench_res_coder_conv0_dat_val, bench_res_coder_conv0_bus |
-- write: bench_ena_coder_conv0_random_data, bench_sti_coder_conv0_dat_val |
-- r/w: |
CODERCONVP : process |
begin |
-- let the system free run |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2); |
-- default state tests: |
if (bench_res_coder_conv0_dat_val = '1') then |
report "CODERCONVP: KO - Default state - Convolutional coder output data is valid" severity warning; |
else |
report "CODERCONVP: OK - Default state - Convolutional coder output data is not valid" severity note; |
end if; |
-- let the system reset |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2 + CCSDS_RXTX_BENCH_START_RESET_SIG_DURATION + CCSDS_RXTX_BENCH_START_CODER_CONV_WAIT_DURATION); |
-- initial state tests: |
if (bench_res_coder_conv0_dat_val = '1') then |
report "CODERCONVP: KO - Initial state - Convolutional coder output data is valid" severity warning; |
else |
report "CODERCONVP: OK - Initial state - Convolutional coder output data is not valid" severity note; |
end if; |
-- behaviour tests: |
report "CODERCONVP: START CONVOLUTIONAL CODER TESTS" severity note; |
bench_ena_coder_conv0_random_data <= '1'; |
wait for CCSDS_RXTX_BENCH_CODER_CONV0_CLK_PERIOD; |
for coder_current_check in 0 to CCSDS_RXTX_BENCH_CODER_CONV0_WORDS_NUMBER-1 loop |
for coder_current_bit in 0 to CCSDS_RXTX_BENCH_CODER_CONV0_DATA_BUS_SIZE loop |
if (coder_current_bit = 0) then |
bench_sti_coder_conv0_dat_val <= '1'; |
else |
bench_sti_coder_conv0_dat_val <= '0'; |
end if; |
wait for CCSDS_RXTX_BENCH_CODER_CONV0_CLK_PERIOD; |
end loop; |
if (bench_res_coder_conv0_dat_val = '0') then |
report "CODERCONVP: KO - Convolutional coder output data is not valid" severity warning; |
else |
if (bench_res_coder_conv0_dat = CCSDS_RXTX_BENCH_CODER_CONV0_OUTPUT) then |
report "CODERCONVP: OK - Convolutional coder output data match" severity note; |
else |
report "CODERCONVP: KO - Convolutional coder output data doesn't match" severity warning; |
end if; |
end if; |
end loop; |
bench_ena_coder_conv0_random_data <= '0'; |
wait for CCSDS_RXTX_BENCH_CODER_CONV0_CLK_PERIOD; |
-- final state tests: |
if (bench_res_coder_conv0_dat_val = '1') then |
report "CODERCONVP: KO - Final state - Convolutional coder output data is valid" severity warning; |
else |
report "CODERCONVP: OK - Final state - Convolutional coder output data is not valid" severity note; |
end if; |
report "CODERCONVP: END CONVOLUTIONAL CODER TESTS" severity note; |
-- do nothing |
wait; |
end process; |
--============================================================================= |
-- Begin of coderdiffp |
-- generation of coder differential subsystem unit-tests |
--============================================================================= |
-- read: bench_res_coder_diff0_dat, bench_res_coder_diff0_dat_val |
-- write: bench_ena_coder_diff0_random_data, bench_sti_coder_diff0_dat_val |
-- r/w: |
CODERDIFFP : process |
begin |
-- let the system free run |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2); |
-- default state tests: |
if (bench_res_coder_diff0_dat_val = '1') then |
report "CODERDIFFP: KO - Default state - Differential coder output data is valid" severity warning; |
else |
report "CODERDIFFP: OK - Default state - Differential coder output data is not valid" severity note; |
end if; |
-- let the system reset |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2 + CCSDS_RXTX_BENCH_START_RESET_SIG_DURATION + CCSDS_RXTX_BENCH_START_CODER_DIFF_WAIT_DURATION); |
-- initial state tests: |
if (bench_res_coder_diff0_dat_val = '1') then |
report "CODERDIFFP: KO - Initial state - Differential coder output data is valid" severity warning; |
else |
report "CODERDIFFP: OK - Initial state - Differential coder output data is not valid" severity note; |
end if; |
-- behaviour tests: |
report "CODERDIFFP: START DIFFERENTIAL CODER TESTS" severity note; |
bench_ena_coder_diff0_random_data <= '1'; |
wait for CCSDS_RXTX_BENCH_CODER_DIFF0_CLK_PERIOD; |
bench_sti_coder_diff0_dat_val <= '1'; |
wait for CCSDS_RXTX_BENCH_CODER_DIFF0_CLK_PERIOD*CCSDS_RXTX_BENCH_CODER_DIFF0_WORDS_NUMBER; |
bench_sti_coder_diff0_dat_val <= '0'; |
bench_ena_coder_diff0_random_data <= '0'; |
wait for CCSDS_RXTX_BENCH_CODER_DIFF0_CLK_PERIOD; |
-- final state tests: |
if (bench_res_coder_diff0_dat_val = '1') then |
report "CODERDIFFP: KO - Final state - Differential coder output data is valid" severity warning; |
else |
report "CODERDIFFP: OK - Final state - Differential coder output data is not valid" severity note; |
end if; |
report "CODERDIFFP: END DIFFERENTIAL CODER TESTS" severity note; |
-- do nothing |
wait; |
end process; |
--============================================================================= |
-- Begin of crcp |
-- generation of crc subsystem unit-tests |
--============================================================================= |
-- read: bench_res_crc0_data, bench_res_crc0_data_valid |
-- write: bench_sti_crc0_nxt, bench_sti_crc0_data, bench_ena_crc0_random_data |
-- r/w: |
CRCP : process |
variable crc_random_data_sent: std_logic_vector(CCSDS_RXTX_BENCH_CRC0_RANDOM_DATA_BUS_SIZE*8-1 downto 0) := (others => '0'); |
variable crc_random_data_crc: std_logic_vector(CCSDS_RXTX_BENCH_CRC0_LENGTH*8-1 downto 0) := (others => '1'); |
variable crc_random_data_crc_check: std_logic_vector(CCSDS_RXTX_BENCH_CRC0_LENGTH*8-1 downto 0) := (others => '0'); |
variable crc_check_ok: std_logic := '1'; |
begin |
-- let the system free run |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2); |
-- default state tests: |
if (bench_res_crc0_data_valid = '1') then |
report "CRCP: KO - Default state - CRC output data is valid" severity warning; |
else |
report "CRCP: OK - Default state - CRC output data is not valid" severity note; |
end if; |
-- let the system reset |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2 + CCSDS_RXTX_BENCH_START_RESET_SIG_DURATION + CCSDS_RXTX_BENCH_START_CRC_WAIT_DURATION); |
-- initial state tests: |
if (bench_res_crc0_data_valid = '1') then |
report "CRCP: KO - Initial state - CRC output data is valid" severity warning; |
else |
report "CRCP: OK - Initial state - CRC output data is not valid" severity note; |
end if; |
-- behaviour tests: |
report "CRCP: START CRC COMPUTATION TESTS" severity note; |
-- present crc test data |
bench_sti_crc0_data <= CCSDS_RXTX_BENCH_CRC0_DATA; |
-- no specific padding done |
bench_sti_crc0_padding_data_valid <= '0'; |
-- send next crc signal |
bench_sti_crc0_nxt <= '1'; |
-- wait for one clk |
wait for CCSDS_RXTX_BENCH_CRC0_CLK_PERIOD; |
-- stop next signal |
bench_sti_crc0_nxt <= '0'; |
-- remove crc test data |
bench_sti_crc0_data <= (others => '0'); |
if (bench_res_crc0_busy = '0') then |
report "CRCP: KO - CRC is not busy" severity warning; |
end if; |
-- wait for result |
wait for CCSDS_RXTX_BENCH_CRC0_CLK_PERIOD*(CCSDS_RXTX_BENCH_CRC0_DATA'length+CCSDS_RXTX_BENCH_CRC0_LENGTH*8+1); |
if (bench_res_crc0_crc = CCSDS_RXTX_BENCH_CRC0_RESULT) and (bench_res_crc0_data_valid = '1') and (bench_res_crc0_data = CCSDS_RXTX_BENCH_CRC0_DATA) then |
report "CRCP: OK - Output CRC is conform to expectations" severity note; |
else |
report "CRCP: KO - Output CRC is different from expectations" severity warning; |
report "Received value:" severity note; |
for i in 0 to bench_res_crc0_data'length-1 loop |
report std_logic'image(bench_res_crc0_data(i)); |
end loop; |
report "Expected value:" severity note; |
for i in 0 to CCSDS_RXTX_BENCH_CRC0_RESULT'length-1 loop |
report std_logic'image(CCSDS_RXTX_BENCH_CRC0_RESULT(i)); |
end loop; |
end if; |
bench_ena_crc0_random_data <= '1'; |
wait for CCSDS_RXTX_BENCH_CRC0_CLK_PERIOD; |
for crc_current_check in 0 to CCSDS_RXTX_BENCH_CRC0_RANDOM_CHECK_NUMBER-1 loop |
-- present crc random data + store associated crc |
-- send next crc signal |
bench_sti_crc0_random_nxt <= '1'; |
-- no specific padding done |
bench_sti_crc0_random_padding_data_valid <= '0'; |
-- wait for one clk and store random data sent |
wait for CCSDS_RXTX_BENCH_CRC0_CLK_PERIOD/2; |
crc_random_data_sent := bench_sti_crc0_random_data; |
wait for CCSDS_RXTX_BENCH_CRC0_CLK_PERIOD/2; |
-- stop next signal |
bench_ena_crc0_random_data <= '0'; |
bench_sti_crc0_random_nxt <= '0'; |
if (bench_res_crc0_random_busy = '0') then |
report "CRCP: KO - random data CRC is not busy" severity warning; |
end if; |
-- wait for result |
wait for CCSDS_RXTX_BENCH_CRC0_CLK_PERIOD*(CCSDS_RXTX_BENCH_CRC0_RANDOM_DATA_BUS_SIZE*8+CCSDS_RXTX_BENCH_CRC0_LENGTH*8+1); |
if (bench_res_crc0_random_data_valid = '1') then |
-- store crc |
crc_random_data_crc := bench_res_crc0_random_crc; |
else |
report "CRCP: KO - random data output CRC is not valid" severity warning; |
end if; |
-- present crc random data |
bench_sti_crc0_check_data <= crc_random_data_sent; |
-- present crc as padding value |
bench_sti_crc0_check_padding_data <= crc_random_data_crc; |
bench_sti_crc0_check_padding_data_valid <= '1'; |
-- send next crc signal |
bench_sti_crc0_check_nxt <= '1'; |
-- wait for one clk |
wait for CCSDS_RXTX_BENCH_CRC0_CLK_PERIOD; |
-- stop next signal |
bench_sti_crc0_check_nxt <= '0'; |
-- stop padding signal |
bench_sti_crc0_check_padding_data_valid <= '0'; |
if (bench_res_crc0_check_busy = '0') then |
report "CRCP: KO - Random data checker CRC is not busy" severity warning; |
end if; |
-- wait for result |
wait for CCSDS_RXTX_BENCH_CRC0_CLK_PERIOD*(CCSDS_RXTX_BENCH_CRC0_RANDOM_DATA_BUS_SIZE*8+CCSDS_RXTX_BENCH_CRC0_LENGTH*8+1); |
if (bench_res_crc0_check_data_valid = '1') then |
-- check output crc resulting is null |
if (bench_res_crc0_check_crc = crc_random_data_crc_check) and (bench_res_crc0_check_data = crc_random_data_sent) then |
if (crc_current_check = CCSDS_RXTX_BENCH_CRC0_RANDOM_CHECK_NUMBER-1) and (crc_check_ok = '1') then |
report "CRCP: OK - Random data checker output CRCs are all null" severity note; |
end if; |
else |
crc_check_ok := '0'; |
report "CRCP: KO - Random data checker output CRC is not null - loop " & integer'image(crc_current_check) severity warning; |
report "Received value:" severity warning; |
for i in 0 to bench_res_crc0_check_data'length-1 loop |
report std_logic'image(bench_res_crc0_check_data(i)) severity warning; |
end loop; |
end if; |
else |
report "CRCP: KO - Output CRC checker is not valid" severity warning; |
end if; |
bench_ena_crc0_random_data <= '1'; |
wait for CCSDS_RXTX_BENCH_CRC0_CLK_PERIOD; |
end loop; |
bench_ena_crc0_random_data <= '0'; |
wait for CCSDS_RXTX_BENCH_CRC0_CLK_PERIOD; |
-- final state tests: |
if (bench_res_crc0_data_valid = '1') then |
report "CRCP: KO - Final state - CRC output data is valid" severity warning; |
else |
report "CRCP: OK - Final state - CRC output data is not valid" severity note; |
end if; |
report "CRCP: END CRC COMPUTATION TESTS" severity note; |
-- do nothing |
wait; |
end process; |
--============================================================================= |
-- Begin of filterp |
-- generation of filter subsystem unit-tests |
--============================================================================= |
-- read: |
-- write: |
-- r/w: |
FILTERP : process |
variable samples_csv_output: line; |
variable samples_hex_output: line; |
variable samples_hex_i_output: line; |
variable samples_hex_q_output: line; |
begin |
-- let the system free run |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2); |
-- default state tests: |
if (bench_res_filter0_sam_val = '0') then |
report "FILTERP: OK - Default state - Output samples are not valid" severity note; |
else |
report "FILTERP: KO - Default state - Output samples are valid" severity warning; |
end if; |
-- let the system reset |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2 + CCSDS_RXTX_BENCH_START_RESET_SIG_DURATION + CCSDS_RXTX_BENCH_START_FILTER_WAIT_DURATION); |
-- initial state tests: |
-- default state tests: |
if (bench_res_filter0_sam_val = '0') then |
report "FILTERP: OK - Initial state - Output samples are not valid" severity note; |
else |
report "FILTERP: KO - Initial state - Output samples are valid" severity warning; |
end if; |
-- behaviour tests: |
report "FILTERP: START FILTER TESTS" severity note; |
if (CCSDS_RXTX_BENCH_OUTPUT_SIGNALS_ENABLE = true) then |
write(samples_csv_output, string'("I samples;Q samples - quantized on " & integer'image(CCSDS_RXTX_BENCH_FILTER0_SIG_QUANT_DEPTH) & " bits / Big-Endian (MSB first) ASCII hexa coded")); |
writeline(CCSDS_RXTX_BENCH_FILTER0_OUTPUT_CSV_IQ_FILE, samples_csv_output); |
end if; |
bench_ena_filter0_random_data <= '1'; |
wait for CCSDS_RXTX_BENCH_FILTER0_MAPPER_DATA_CLK_PERIOD; |
bench_sti_filter0_mapper_dat_val <= '1'; |
wait for CCSDS_RXTX_BENCH_FILTER0_BITS_PER_SYMBOL*CCSDS_RXTX_BENCH_FILTER0_MAPPER_DATA_CLK_PERIOD*CCSDS_RXTX_BENCH_FILTER0_BITS_PER_SYMBOL/CCSDS_RXTX_BENCH_FILTER0_MODULATION_TYPE; |
if (CCSDS_RXTX_BENCH_OUTPUT_SIGNALS_ENABLE = true) then |
for i in 0 to 200 loop |
wait for CCSDS_RXTX_BENCH_FILTER0_CLK_PERIOD; |
if (bench_res_filter0_sam_val = '1') then |
write(samples_csv_output, convert_std_logic_vector_to_hexa_ascii(bench_res_filter0_sam_i) & ";"); |
write(samples_csv_output, convert_std_logic_vector_to_hexa_ascii(bench_res_filter0_sam_q)); |
write(samples_hex_output, convert_std_logic_vector_to_hexa_ascii(bench_res_filter0_sam_i)); |
write(samples_hex_output, convert_std_logic_vector_to_hexa_ascii(bench_res_filter0_sam_q)); |
writeline(CCSDS_RXTX_BENCH_FILTER0_OUTPUT_CSV_IQ_FILE, samples_csv_output); |
writeline(CCSDS_RXTX_BENCH_FILTER0_OUTPUT_HEX_IQ_FILE, samples_hex_output); |
write(samples_hex_i_output, convert_std_logic_vector_to_hexa_ascii(bench_res_filter0_sam_i)); |
write(samples_hex_q_output, convert_std_logic_vector_to_hexa_ascii(bench_res_filter0_sam_q)); |
writeline(CCSDS_RXTX_BENCH_FILTER0_OUTPUT_HEX_I_FILE, samples_hex_i_output); |
writeline(CCSDS_RXTX_BENCH_FILTER0_OUTPUT_HEX_Q_FILE, samples_hex_q_output); |
else |
report "FILTERP: KO - Output samples are not valid" severity warning; |
end if; |
end loop; |
else |
wait for 200*CCSDS_RXTX_BENCH_FILTER0_CLK_PERIOD; |
end if; |
if (bench_res_filter0_sam_val = '1') then |
report "FILTERP: OK - Output samples are valid" severity note; |
else |
report "FILTERP: KO - Output samples are not valid" severity warning; |
end if; |
if (CCSDS_RXTX_BENCH_OUTPUT_SIGNALS_ENABLE = true) then |
for i in 0 to CCSDS_RXTX_BENCH_FILTER0_SYMBOL_WORDS_NUMBER-1 loop |
for j in 0 to CCSDS_RXTX_BENCH_FILTER0_MAPPER_CLK_PERIOD/CCSDS_RXTX_BENCH_FILTER0_CLK_PERIOD-1 loop |
wait for CCSDS_RXTX_BENCH_FILTER0_CLK_PERIOD; |
if (bench_res_filter0_sam_val = '1') then |
write(samples_csv_output, convert_std_logic_vector_to_hexa_ascii(bench_res_filter0_sam_i) & ";"); |
write(samples_csv_output, convert_std_logic_vector_to_hexa_ascii(bench_res_filter0_sam_q)); |
write(samples_hex_output, convert_std_logic_vector_to_hexa_ascii(bench_res_filter0_sam_i)); |
write(samples_hex_output, convert_std_logic_vector_to_hexa_ascii(bench_res_filter0_sam_q)); |
writeline(CCSDS_RXTX_BENCH_FILTER0_OUTPUT_CSV_IQ_FILE, samples_csv_output); |
writeline(CCSDS_RXTX_BENCH_FILTER0_OUTPUT_HEX_IQ_FILE, samples_hex_output); |
write(samples_hex_i_output, convert_std_logic_vector_to_hexa_ascii(bench_res_filter0_sam_i)); |
write(samples_hex_q_output, convert_std_logic_vector_to_hexa_ascii(bench_res_filter0_sam_q)); |
writeline(CCSDS_RXTX_BENCH_FILTER0_OUTPUT_HEX_I_FILE, samples_hex_i_output); |
writeline(CCSDS_RXTX_BENCH_FILTER0_OUTPUT_HEX_Q_FILE, samples_hex_q_output); |
else |
report "FILTERP: KO - Output samples are not valid" severity warning; |
end if; |
end loop; |
end loop; |
else |
wait for CCSDS_RXTX_BENCH_FILTER0_MAPPER_CLK_PERIOD*CCSDS_RXTX_BENCH_FILTER0_SYMBOL_WORDS_NUMBER; |
end if; |
bench_sti_filter0_mapper_dat_val <= '0'; |
bench_ena_filter0_random_data <= '0'; |
wait for CCSDS_RXTX_BENCH_FILTER0_MAPPER_CLK_PERIOD*12; |
-- final state tests: |
if (bench_res_filter0_sam_val = '0') then |
report "FILTERP: OK - Final state - Output samples are not valid" severity note; |
else |
report "FILTERP: KO - Final state - Output samples are valid" severity warning; |
end if; |
report "FILTERP: END FILTER TESTS" severity note; |
-- do nothing |
wait; |
end process; |
--============================================================================= |
-- Begin of framerp |
-- generation of framer subsystem unit-tests |
--============================================================================= |
-- read: bench_res_framer0_data0, bench_res_framer0_data_valid0 |
-- write: bench_ena_framer0_random_data |
-- r/w: |
FRAMERP : process |
type data_array is array (CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH*8/CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE-1 downto 0) of std_logic_vector(CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE-1 downto 0); |
type frame_array is array (CCSDS_RXTX_BENCH_FRAMER0_FRAME_NUMBER-1 downto 0) of data_array; |
variable framer_expected_data: frame_array := (others => (others => (others => '0'))); |
variable frame_content_ok: std_logic := '1'; |
variable nb_data: integer; |
variable FRAME_OUTPUT_CYCLES_REQUIRED: integer; |
variable FRAME_PROCESSING_CYCLES_REQUIRED: integer := (CCSDS_RXTX_BENCH_FRAMER0_HEADER_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_FOOTER_LENGTH)*8+1; |
constant FRAME_ACQUISITION_CYCLES: integer := (CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH*8-CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE)*CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO/CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE + 1; |
constant FRAME_REPETITION_CYCLES: integer := CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH*8*CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO/CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE; |
constant FRAME_ACQUISITION_CYCLES_IDLE: integer := FRAME_REPETITION_CYCLES - FRAME_ACQUISITION_CYCLES; |
begin |
if (CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH*8 = CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE) and (CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO = 1) then |
FRAME_OUTPUT_CYCLES_REQUIRED := (CCSDS_RXTX_BENCH_FRAMER0_HEADER_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_FOOTER_LENGTH)*8+6; |
else |
FRAME_OUTPUT_CYCLES_REQUIRED := (CCSDS_RXTX_BENCH_FRAMER0_HEADER_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_FOOTER_LENGTH)*8+5; |
end if; |
-- let the system free run |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2); |
-- default state tests: |
-- let the system reset |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2 + CCSDS_RXTX_BENCH_START_RESET_SIG_DURATION + CCSDS_RXTX_BENCH_START_FRAMER_WAIT_DURATION); |
report "FRAMERP: START FRAMER TESTS" severity note; |
-- initial state tests: |
bench_ena_framer0_random_data <= '1'; |
-- check output data is valid and idle only data found |
if ((CCSDS_RXTX_BENCH_START_FRAMER_WAIT_DURATION/CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD) < FRAME_OUTPUT_CYCLES_REQUIRED) then |
wait for (FRAME_OUTPUT_CYCLES_REQUIRED+1 - ((CCSDS_RXTX_BENCH_START_FRAMER_WAIT_DURATION/CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD) mod FRAME_OUTPUT_CYCLES_REQUIRED))*CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD; |
else |
wait for (FRAME_REPETITION_CYCLES+1 - (((CCSDS_RXTX_BENCH_START_FRAMER_WAIT_DURATION/CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD) - FRAME_OUTPUT_CYCLES_REQUIRED) mod (FRAME_REPETITION_CYCLES)))*CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD; |
end if; |
if bench_res_framer0_data_valid = '1' then |
if (bench_res_framer0_data((CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_FOOTER_LENGTH)*8+10 downto (CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_FOOTER_LENGTH)*8) = "11111111110") then |
report "FRAMERP: OK - Initial state - Output frame is valid and Only Idle Data flag found" severity note; |
else |
report "FRAMERP: KO - Initial state - Output frame is valid without sent data - Only Idle Flag not found" severity warning; |
end if; |
else |
report "FRAMERP: KO - Initial state - Output frame is not valid without sent data" severity warning; |
end if; |
if (bench_res_framer0_dat_nxt = '0') then |
report "FRAMERP: KO - Initial state - Next data not requested" severity warning; |
else |
report "FRAMERP: OK - Initial state - Next data requested" severity note; |
end if; |
-- behaviour tests: |
-- align the end of data to the beginning of a new frame processing cycle |
wait for CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD*(FRAME_REPETITION_CYCLES - (FRAME_OUTPUT_CYCLES_REQUIRED mod FRAME_REPETITION_CYCLES) + FRAME_ACQUISITION_CYCLES_IDLE); |
-- send data for 1 frame |
for i in 0 to (CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH*8/CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE)-1 loop |
bench_sti_framer0_data_valid <= '1'; |
wait for CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD/2; |
framer_expected_data(0)(i) := bench_sti_framer0_data; |
wait for CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD/2; |
if (i /= (CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH*8/CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE)-1) then |
if (CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO /= 1) then |
bench_sti_framer0_data_valid <= '0'; |
wait for (CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO-1)*CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD; |
end if; |
end if; |
end loop; |
bench_sti_framer0_data_valid <= '0'; |
bench_ena_framer0_random_data <= '0'; |
-- wait for footer to be processed |
wait for CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD*(FRAME_PROCESSING_CYCLES_REQUIRED+4); |
if bench_res_framer0_data_valid = '0' then |
report "FRAMERP: KO - Output frame is not ready in time" severity warning; |
else |
report "FRAMERP: OK - Output frame is ready in time" severity note; |
-- check frame content is coherent with sent data |
for i in 0 to (CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH*8/CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE)-1 loop |
if (bench_res_framer0_data((CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_FOOTER_LENGTH)*8-CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE*i-1 downto (CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_FOOTER_LENGTH)*8-CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE*(i+1)) /= framer_expected_data(0)(i)) then |
report "FRAMERP: KO - Output frame content is not equal to sent data - loop: " & integer'image(i) severity warning; |
frame_content_ok := '0'; |
else |
if (i = (CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH*8/CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE)-1) and (frame_content_ok = '1') then |
report "FRAMERP: OK - Output frame is equal to sent data" severity note; |
end if; |
end if; |
end loop; |
end if; |
-- send data every CCSDS_TX_FRAMER_PARALLELISM_MAX_RATIO clk during CCSDS_RXTX_BENCH_FRAMER0_FRAME_NUMBER*frame_processing time, store sent data for first frame and check output frame content |
bench_ena_framer0_random_data <= '1'; |
-- align the end of data to the beginning of a new frame processing cycle |
wait for CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD*(FRAME_REPETITION_CYCLES - (FRAME_OUTPUT_CYCLES_REQUIRED mod FRAME_REPETITION_CYCLES) + FRAME_ACQUISITION_CYCLES_IDLE); |
frame_content_ok := '1'; |
for f in 0 to (CCSDS_RXTX_BENCH_FRAMER0_FRAME_NUMBER-1) loop |
for i in 0 to (CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH*8/CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE)-1 loop |
bench_sti_framer0_data_valid <= '1'; |
wait for CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD/2; |
framer_expected_data(f)(i) := bench_sti_framer0_data; |
wait for CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD/2; |
if (CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO /= 1) then |
bench_sti_framer0_data_valid <= '0'; |
wait for (CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO-1)*CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD; |
end if; |
end loop; |
-- waiting for footer to be processed |
for data_packet in 0 to ((FRAME_PROCESSING_CYCLES_REQUIRED-1)/CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO)-1 loop |
bench_sti_framer0_data_valid <= '1'; |
wait for CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD; |
if (data_packet /= ((FRAME_PROCESSING_CYCLES_REQUIRED-1)/CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO-1)) then |
if (CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO /= 1) then |
bench_sti_framer0_data_valid <= '0'; |
wait for (CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO-1)*CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD; |
end if; |
end if; |
end loop; |
if (CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO /= 1) then |
bench_sti_framer0_data_valid <= '0'; |
end if; |
wait for 5*CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD; |
if bench_res_framer0_data_valid = '0' then |
report "FRAMERP: KO - Output frame is not ready in time - frame loop: " & integer'image(f) severity warning; |
else |
-- check frame content is coherent with sent data |
for i in 0 to (CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH*8/CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE)-1 loop |
if (bench_res_framer0_data((CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_FOOTER_LENGTH)*8-CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE*i-1 downto (CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_FOOTER_LENGTH)*8-CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE*(i+1)) /= framer_expected_data(f)(i)) then |
report "FRAMERP: KO - Output frame content is not equal to sent data - frame loop: " & integer'image(f) & " - data loop: " & integer'image(i) severity warning; |
frame_content_ok := '0'; |
else |
if (i = (CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH*8/CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE)-1) and (f = (CCSDS_RXTX_BENCH_FRAMER0_FRAME_NUMBER-1)) and (frame_content_ok = '1') then |
report "FRAMERP: OK - Received output frames are all equal to sent data" severity note; |
end if; |
end if; |
end loop; |
end if; |
if (f /= (CCSDS_RXTX_BENCH_FRAMER0_FRAME_NUMBER-1)) then |
-- fill current frame to start with new one |
if ((((CCSDS_RXTX_BENCH_FRAMER0_HEADER_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_FOOTER_LENGTH)*8) mod FRAME_REPETITION_CYCLES) /= 0) then |
nb_data := (FRAME_REPETITION_CYCLES - (((CCSDS_RXTX_BENCH_FRAMER0_HEADER_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_FOOTER_LENGTH)*8) mod FRAME_REPETITION_CYCLES))/CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO; |
for i in 0 to nb_data-1 loop |
bench_sti_framer0_data_valid <= '1'; |
wait for CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD; |
if (CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO /= 1) then |
bench_sti_framer0_data_valid <= '0'; |
wait for (CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO-1)*CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD; |
end if; |
end loop; |
-- align the end of data to the beginning of a new frame processing cycle |
wait for CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD*(2*FRAME_REPETITION_CYCLES - (FRAME_OUTPUT_CYCLES_REQUIRED mod FRAME_REPETITION_CYCLES) + FRAME_ACQUISITION_CYCLES_IDLE - nb_data*CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO); |
else |
-- align the end of data to the beginning of a new frame processing cycle |
wait for CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD*(FRAME_REPETITION_CYCLES - (FRAME_OUTPUT_CYCLES_REQUIRED mod FRAME_REPETITION_CYCLES) + FRAME_ACQUISITION_CYCLES_IDLE); |
end if; |
end if; |
end loop; |
bench_sti_framer0_data_valid <= '0'; |
-- wait for last frame to be processed and presented |
wait for CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD*(FRAME_REPETITION_CYCLES*(((FRAME_PROCESSING_CYCLES_REQUIRED+1)/FRAME_REPETITION_CYCLES)+4)); |
-- send data continuously to test full-speed / overflow behaviour |
bench_sti_framer0_data_valid <= '1'; |
wait for (CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO*CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO*CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH*8/CCSDS_RXTX_BENCH_FRAMER0_DATA_BUS_SIZE)*CCSDS_RXTX_BENCH_FRAMER0_CLK_PERIOD; |
if (CCSDS_RXTX_BENCH_FRAMER0_PARALLELISM_MAX_RATIO /= 1) then |
if (bench_res_framer0_dat_nxt = '0') then |
report "FRAMERP: OK - Overflow stop next data request" severity note; |
else |
report "FRAMERP: KO - Overflow doesn't stop next data request" severity warning; |
end if; |
else |
if (bench_res_framer0_dat_nxt = '1') then |
report "FRAMERP: OK - Full speed doesn't stop next data request" severity note; |
else |
report "FRAMERP: KO - Full speed stop next data request" severity warning; |
end if; |
end if; |
bench_sti_framer0_data_valid <= '0'; |
bench_ena_framer0_random_data <= '0'; |
-- final state tests: |
if bench_res_framer0_data_valid = '1' then |
if (bench_res_framer0_data((CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_FOOTER_LENGTH)*8+10 downto (CCSDS_RXTX_BENCH_FRAMER0_DATA_LENGTH+CCSDS_RXTX_BENCH_FRAMER0_FOOTER_LENGTH)*8) = "11111111110") then |
report "FRAMERP: OK - Final state - Output frame is valid and Only Idle Data flag found" severity note; |
else |
report "FRAMERP: KO - Final state - Output frame is valid without sent data - Only Idle Flag not found" severity warning; |
end if; |
else |
report "FRAMERP: KO - Final state - Output frame is not valid without sent data" severity warning; |
end if; |
if (bench_res_framer0_dat_nxt = '0') then |
report "FRAMERP: KO - Final state - Next data not requested" severity warning; |
else |
report "FRAMERP: OK - Final state - Next data requested" severity note; |
end if; |
report "FRAMERP: END FRAMER TESTS" severity note; |
-- do nothing |
wait; |
end process; |
--============================================================================= |
-- Begin of lfsrp |
-- generation of lfsr subsystem unit-tests |
--============================================================================= |
-- read: bench_res_lfsr0_data, bench_res_lfsr0_data_valid |
-- write: |
-- r/w: |
LFSRP : process |
begin |
-- let the system free run |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2); |
-- default state tests: |
-- let the system reset |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2 + CCSDS_RXTX_BENCH_START_RESET_SIG_DURATION + CCSDS_RXTX_BENCH_START_LFSR_WAIT_DURATION); |
-- initial state tests: |
-- behaviour tests: |
report "LFSRP: START LFSR TESTS" severity note; |
wait for (CCSDS_RXTX_BENCH_LFSR0_RESULT'length)*CCSDS_RXTX_BENCH_LFSR0_CLK_PERIOD; |
if (bench_res_lfsr0_data_valid = '1') then |
report "LFSRP: OK - LFSR output is valid" severity note; |
if (bench_res_lfsr0_data = CCSDS_RXTX_BENCH_LFSR0_RESULT) then |
report "LFSRP: OK - LFSR output is equal to expected output" severity note; |
else |
report "LFSRP: KO - LFSR output is different from expected output" severity warning; |
end if; |
else |
report "LFSRP: KO - LFSR output is not valid" severity warning; |
end if; |
-- final state tests: |
report "LFSRP: END LFSR TESTS" severity note; |
-- do nothing |
wait; |
end process; |
--============================================================================= |
-- Begin of mapperbitssymbolsp |
-- generation of mapper subsystem unit-tests |
--============================================================================= |
-- read: |
-- write: bench_sti_mapper_bits_symbols0_dat_val, bench_sti_mapper_bits_symbols0_dat_val |
-- r/w: |
MAPPERBITSSYMBOLSP : process |
begin |
-- let the system free run |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2); |
-- default state tests: |
if (bench_res_mapper_bits_symbols0_sym_val = '1') then |
report "MAPPERBITSSYMBOLSP: KO - Default state - Mapper output data is valid" severity warning; |
else |
report "MAPPERBITSSYMBOLSP: OK - Default state - Mapper output data is not valid" severity note; |
end if; |
-- let the system reset |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2 + CCSDS_RXTX_BENCH_START_RESET_SIG_DURATION + CCSDS_RXTX_BENCH_START_MAPPER_BITS_SYMBOLS_WAIT_DURATION); |
-- initial state tests: |
if (bench_res_mapper_bits_symbols0_sym_val = '1') then |
report "MAPPERBITSSYMBOLSP: KO - Initial state - Mapper output data is valid" severity warning; |
else |
report "MAPPERBITSSYMBOLSP: OK - Initial state - Mapper output data is not valid" severity note; |
end if; |
-- behaviour tests: |
report "MAPPERBITSSYMBOLSP: START BITS TO SYMBOLS MAPPER TESTS" severity note; |
bench_ena_mapper_bits_symbols0_random_data <= '1'; |
wait for CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_DATA_CLK_PERIOD; |
bench_sti_mapper_bits_symbols0_dat_val <= '1'; |
wait for CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_DATA_CLK_PERIOD*CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_DATA_BUS_SIZE/CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_BITS_PER_SYMBOL*CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_WORDS_NUMBER; |
bench_sti_mapper_bits_symbols0_dat_val <= '0'; |
bench_ena_mapper_bits_symbols0_random_data <= '0'; |
wait for CCSDS_RXTX_BENCH_MAPPER_BITS_SYMBOLS0_DATA_CLK_PERIOD; |
-- final state tests: |
if (bench_res_mapper_bits_symbols0_sym_val = '1') then |
report "MAPPERBITSSYMBOLSP: KO - Final state - Mapper output data is valid" severity warning; |
else |
report "MAPPERBITSSYMBOLSP: OK - Final state - Mapper output data is not valid" severity note; |
end if; |
report "MAPPERBITSSYMBOLSP: END BITS TO SYMBOLS MAPPER TESTS" severity note; |
-- do nothing |
wait; |
end process; |
--============================================================================= |
-- Begin of mappersymbolssamplesp |
-- generation of mapper subsystem unit-tests |
--============================================================================= |
-- read: |
-- write: bench_sti_mapper_bits_symbols0_dat_val, bench_sti_mapper_bits_symbols0_dat_val |
-- r/w: |
MAPPERSYMBOLSSAMPLESP : process |
begin |
-- let the system free run |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2); |
-- default state tests: |
if (bench_res_mapper_symbols_samples0_sam_val = '1') then |
report "MAPPERSYMBOLSSAMPLESP: KO - Default state - Mapper output data is valid" severity warning; |
else |
report "MAPPERSYMBOLSSAMPLESP: OK - Default state - Mapper output data is not valid" severity note; |
end if; |
-- let the system reset |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2 + CCSDS_RXTX_BENCH_START_RESET_SIG_DURATION + CCSDS_RXTX_BENCH_START_MAPPER_SYMBOLS_SAMPLES_WAIT_DURATION); |
-- initial state tests: |
if (bench_res_mapper_symbols_samples0_sam_val = '1') then |
report "MAPPERSYMBOLSSAMPLESP: KO - Initial state - Mapper output data is valid" severity warning; |
else |
report "MAPPERSYMBOLSSAMPLESP: OK - Initial state - Mapper output data is not valid" severity note; |
end if; |
-- behaviour tests: |
report "MAPPERSYMBOLSSAMPLESP: START SYMBOLS TO SAMPLES MAPPER TESTS" severity note; |
bench_ena_mapper_symbols_samples0_random_data <= '1'; |
wait for CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_CLK_PERIOD; |
bench_sti_mapper_symbols_samples0_sym_val <= '1'; |
wait for CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_CLK_PERIOD*CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_WORDS_NUMBER; |
bench_sti_mapper_symbols_samples0_sym_val <= '0'; |
bench_ena_mapper_symbols_samples0_random_data <= '0'; |
wait for CCSDS_RXTX_BENCH_MAPPER_SYMBOLS_SAMPLES0_CLK_PERIOD; |
-- final state tests: |
if (bench_res_mapper_symbols_samples0_sam_val = '1') then |
report "MAPPERSYMBOLSSAMPLESP: KO - Final state - Mapper output data is valid" severity warning; |
else |
report "MAPPERSYMBOLSSAMPLESP: OK - Final state - Mapper output data is not valid" severity note; |
end if; |
report "MAPPERSYMBOLSSAMPLESP: END SYMBOLS TO SAMPLES MAPPER TESTS" severity note; |
-- do nothing |
wait; |
end process; |
--============================================================================= |
-- Begin of serdesp |
-- generation of serdes subsystem unit-tests |
--============================================================================= |
-- read: bench_res_serdes0_data_par_valid, bench_res_serdes0_data_par, bench_res_serdes0_data_ser, bench_res_serdes0_data_ser_valid, bench_res_serdes0_busy |
-- write: bench_sti_serdes0_data_par_valid, bench_sti_serdes0_data_ser_valid, bench_ena_serdes0_random_data |
-- r/w: |
SERDESP : process |
variable serdes_expected_output: std_logic_vector(CCSDS_RXTX_BENCH_SERDES0_DEPTH-1 downto 0) := (others => '0'); |
variable serdes_ok: std_logic := '1'; |
begin |
-- let the system free run |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2); |
-- default state tests: |
-- check serdes is not valid |
if (bench_res_serdes0_data_par_valid = '0') then |
report "SERDESP: OK - Default state - Serdes parallel output is not valid" severity note; |
else |
report "SERDESP: KO - Default state - Serdes parallel output is valid" severity warning; |
end if; |
if (bench_res_serdes0_data_ser_valid = '0') then |
report "SERDESP: OK - Default state - Serdes serial output is not valid" severity note; |
else |
report "SERDESP: KO - Default state - Serdes serial output is valid" severity warning; |
end if; |
if (bench_res_serdes0_busy = '0') then |
report "SERDESP: OK - Default state - Serdes is not busy" severity note; |
else |
report "SERDESP: KO - Default state - Serdes is busy" severity warning; |
end if; |
-- let the system reset |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2 + CCSDS_RXTX_BENCH_START_RESET_SIG_DURATION + CCSDS_RXTX_BENCH_START_SERDES_WAIT_DURATION); |
-- initial state tests: |
-- check serdes is not valid |
if (bench_res_serdes0_data_par_valid = '0') then |
report "SERDESP: OK - Initial state - Serdes parallel output is not valid" severity note; |
else |
report "SERDESP: KO - Initial state - Serdes parallel output is valid" severity warning; |
end if; |
if (bench_res_serdes0_data_ser_valid = '0') then |
report "SERDESP: OK - Initial state - Serdes serial output is not valid" severity note; |
else |
report "SERDESP: KO - Initial state - Serdes serial output is valid" severity warning; |
end if; |
if (bench_res_serdes0_busy = '0') then |
report "SERDESP: OK - Initial state - Serdes is not busy" severity note; |
else |
report "SERDESP: KO - Initial state - Serdes is busy" severity warning; |
end if; |
-- behaviour tests: |
report "SERDESP: START SERDES TESTS" severity note; |
bench_ena_serdes0_random_data <= '1'; |
wait for CCSDS_RXTX_BENCH_SERDES0_CLK_PERIOD; |
-- test par2ser |
-- signal valid parallel data input |
bench_sti_serdes0_data_par_valid <= '1'; |
wait for CCSDS_RXTX_BENCH_SERDES0_CLK_PERIOD/2; |
serdes_expected_output := bench_sti_serdes0_data_par; |
wait for CCSDS_RXTX_BENCH_SERDES0_CLK_PERIOD/2; |
bench_sti_serdes0_data_par_valid <= '0'; |
for bit_pointer in (CCSDS_RXTX_BENCH_SERDES0_DEPTH-1) downto 0 loop |
if (bench_res_serdes0_busy = '0') then |
report "SERDESP: KO - Serdes is not busy" severity warning; |
else |
if (bench_res_serdes0_data_ser_valid = '1') then |
if (bench_res_serdes0_data_ser /= serdes_expected_output(bit_pointer)) then |
serdes_ok := '0'; |
report "SERDESP: KO - Serdes serialized output data doesn't match expected output - cycle " & integer'image(bit_pointer) severity warning; |
report "Expected value: " & std_logic'image(serdes_expected_output(bit_pointer)) severity warning; |
report "Received value: " & std_logic'image(bench_res_serdes0_data_ser) severity warning; |
else |
if (serdes_ok = '1') and (bit_pointer = 0) then |
report "SERDESP: OK - Serdes serialized output data match expected output" severity note; |
end if; |
end if; |
else |
report "SERDESP: KO - Serdes serialized output data is not valid" severity warning; |
end if; |
end if; |
wait for CCSDS_RXTX_BENCH_SERDES0_CLK_PERIOD; |
end loop; |
-- test ser2par |
-- signal valid serial data input |
serdes_expected_output := (others => '0'); |
bench_sti_serdes0_data_ser_valid <= '1'; |
for bit_pointer in (CCSDS_RXTX_BENCH_SERDES0_DEPTH-1) downto 0 loop |
wait for CCSDS_RXTX_BENCH_SERDES0_CLK_PERIOD/2; |
serdes_expected_output(bit_pointer) := bench_sti_serdes0_data_ser; |
wait for CCSDS_RXTX_BENCH_SERDES0_CLK_PERIOD/2; |
end loop; |
bench_sti_serdes0_data_ser_valid <= '0'; |
bench_ena_serdes0_random_data <= '0'; |
if (bench_res_serdes0_data_par_valid = '1') then |
report "SERDESP: OK - Serdes parallelized output data is valid" severity note; |
if (bench_res_serdes0_data_par = serdes_expected_output) then |
report "SERDESP: OK - Serdes parallelized output data match expected output" severity note; |
else |
report "SERDESP: KO - Serdes parallelized output data doesn't match expected output" severity warning; |
report "Expected value:" severity warning; |
for bit_pointer in 0 to CCSDS_RXTX_BENCH_SERDES0_DEPTH-1 loop |
report std_logic'image(serdes_expected_output(bit_pointer)) severity warning; |
end loop; |
report "Received value:" severity warning; |
for bit_pointer in 0 to CCSDS_RXTX_BENCH_SERDES0_DEPTH-1 loop |
report std_logic'image(bench_res_serdes0_data_par(bit_pointer)) severity warning; |
end loop; |
end if; |
else |
report "SERDESP: KO - Serdes parallelized output data is not valid" severity warning; |
end if; |
wait for CCSDS_RXTX_BENCH_SERDES0_CLK_PERIOD; |
--TODO: TEST SER2PAR + PAR2SER SIMULTANEOUSLY |
-- many par2ser cycles |
bench_ena_serdes0_random_data <= '1'; |
serdes_expected_output := (others => '0'); |
serdes_ok := '1'; |
for cycle_number in 0 to CCSDS_RXTX_BENCH_SERDES0_CYCLES_NUMBER-1 loop |
for bit_pointer in (CCSDS_RXTX_BENCH_SERDES0_DEPTH-1) downto 0 loop |
if (bit_pointer = (CCSDS_RXTX_BENCH_SERDES0_DEPTH-1)) then |
-- signal valid parallel data input |
bench_sti_serdes0_data_par_valid <= '1'; |
wait for CCSDS_RXTX_BENCH_SERDES0_CLK_PERIOD/2; |
serdes_expected_output := bench_sti_serdes0_data_par; |
wait for CCSDS_RXTX_BENCH_SERDES0_CLK_PERIOD/2; |
bench_sti_serdes0_data_par_valid <= '0'; |
else |
wait for CCSDS_RXTX_BENCH_SERDES0_CLK_PERIOD; |
end if; |
if (bench_res_serdes0_busy = '0') then |
report "SERDESP: KO - Serdes is not busy" severity warning; |
else |
if (bench_res_serdes0_data_ser_valid = '1') then |
if (bench_res_serdes0_data_ser /= serdes_expected_output(bit_pointer)) then |
serdes_ok := '0'; |
report "SERDESP: KO - Serdes serialized output data doesn't match expected output - cycle " & integer'image(bit_pointer) severity warning; |
report "Expected value: " & std_logic'image(serdes_expected_output(bit_pointer)) severity warning; |
report "Received value: " & std_logic'image(bench_res_serdes0_data_ser) severity warning; |
else |
if (serdes_ok = '1') and (bit_pointer = 0) and (cycle_number = (CCSDS_RXTX_BENCH_SERDES0_CYCLES_NUMBER-1)) then |
report "SERDESP: OK - All serdes serialized output data match expected outputs" severity note; |
end if; |
end if; |
else |
report "SERDESP: KO - Serdes serialized output data is not valid" severity warning; |
end if; |
end if; |
end loop; |
end loop; |
-- many par2ser cycles |
serdes_expected_output := (others => '0'); |
serdes_ok := '1'; |
for cycle_number in 0 to CCSDS_RXTX_BENCH_SERDES0_CYCLES_NUMBER-1 loop |
-- signal valid serial data input |
bench_sti_serdes0_data_ser_valid <= '1'; |
for bit_pointer in (CCSDS_RXTX_BENCH_SERDES0_DEPTH-1) downto 0 loop |
wait for CCSDS_RXTX_BENCH_SERDES0_CLK_PERIOD/2; |
serdes_expected_output(bit_pointer) := bench_sti_serdes0_data_ser; |
wait for CCSDS_RXTX_BENCH_SERDES0_CLK_PERIOD/2; |
end loop; |
if (bench_res_serdes0_data_par_valid = '1') then |
if (bench_res_serdes0_data_par = serdes_expected_output) then |
if (cycle_number = (CCSDS_RXTX_BENCH_SERDES0_CYCLES_NUMBER-1)) and (serdes_ok = '1') then |
report "SERDESP: OK - All serdes parallelized output data match expected outputs" severity note; |
end if; |
else |
serdes_ok := '0'; |
report "SERDESP: KO - Serdes parallelized output data doesn't match expected output" severity warning; |
report "Expected value:" severity warning; |
for bit_pointer in 0 to CCSDS_RXTX_BENCH_SERDES0_DEPTH-1 loop |
report std_logic'image(serdes_expected_output(bit_pointer)) severity warning; |
end loop; |
report "Received value:" severity warning; |
for bit_pointer in 0 to CCSDS_RXTX_BENCH_SERDES0_DEPTH-1 loop |
report std_logic'image(bench_res_serdes0_data_par(bit_pointer)) severity warning; |
end loop; |
end if; |
else |
report "SERDESP: KO - Serdes parallelized output data is not valid" severity warning; |
end if; |
end loop; |
bench_sti_serdes0_data_ser_valid <= '0'; |
bench_ena_serdes0_random_data <= '0'; |
wait for CCSDS_RXTX_BENCH_SERDES0_CLK_PERIOD; |
-- final state tests: |
-- check serdes is not valid |
if (bench_res_serdes0_data_par_valid = '0') then |
report "SERDESP: OK - Final state - Serdes parallel output is not valid" severity note; |
else |
report "SERDESP: KO - Final state - Serdes parallel output is valid" severity warning; |
end if; |
if (bench_res_serdes0_data_ser_valid = '0') then |
report "SERDESP: OK - Final state - Serdes serial output is not valid" severity note; |
else |
report "SERDESP: KO - Final state - Serdes serial output is valid" severity warning; |
end if; |
if (bench_res_serdes0_busy = '0') then |
report "SERDESP: OK - Final state - Serdes is not busy" severity note; |
else |
report "SERDESP: KO - Final state - Serdes is busy" severity warning; |
end if; |
report "SERDESP: END SERDES TESTS" severity note; |
-- do nothing |
wait; |
end process; |
--============================================================================= |
-- Begin of srrcp |
-- generation of SRRC subsystem unit-tests |
--============================================================================= |
-- read: |
-- write: |
-- r/w: |
SRRCP : process |
constant srrc_zero: std_logic_vector(CCSDS_RXTX_BENCH_SRRC0_SIG_QUANT_DEPTH-1 downto 0) := (others => '0'); |
variable samples_hex_output: line; |
begin |
-- let the system free run |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2); |
-- default state tests: |
if (bench_res_srrc0_sam_val = '0') then |
report "SRRCP: OK - Default state - SRRC samples are not valid" severity note; |
else |
report "SRRCP: KO - Default state - SRRC samples are valid" severity warning; |
end if; |
-- let the system reset |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2 + CCSDS_RXTX_BENCH_START_RESET_SIG_DURATION + CCSDS_RXTX_BENCH_START_SRRC_WAIT_DURATION); |
-- initial state tests: |
if (bench_res_srrc0_sam_val = '0') then |
report "SRRCP: OK - Initial state - SRRC samples are not valid" severity note; |
else |
report "SRRCP: KO - Initial state - SRRC samples are valid" severity warning; |
end if; |
if (bench_res_srrc0_sam = srrc_zero) then |
report "SRRCP: OK - Initial state - SRRC samples are null" severity note; |
else |
report "SRRCP: KO - Initial state - SRRC samples are not null" severity warning; |
end if; |
-- behaviour tests: |
report "SRRCP: START SRRC TESTS" severity note; |
bench_sti_srrc0_sam(CCSDS_RXTX_BENCH_SRRC0_SIG_QUANT_DEPTH-1) <= '0'; |
bench_sti_srrc0_sam(CCSDS_RXTX_BENCH_SRRC0_SIG_QUANT_DEPTH-2 downto 0) <= (others => '1'); |
bench_sti_srrc0_sam_val <= '1'; |
wait for CCSDS_RXTX_BENCH_SRRC0_CLK_PERIOD; |
bench_sti_srrc0_sam <= (others => '0'); |
if (CCSDS_RXTX_BENCH_OUTPUT_SIGNALS_ENABLE = true) then |
for i in 0 to 400 loop |
wait for CCSDS_RXTX_BENCH_SRRC0_CLK_PERIOD; |
if (bench_res_srrc0_sam_val = '1') then |
write(samples_hex_output, convert_std_logic_vector_to_hexa_ascii(bench_res_srrc0_sam)); |
writeline(CCSDS_RXTX_BENCH_SRRC0_OUTPUT_HEX_FILE, samples_hex_output); |
else |
report "SRRCP: KO - SRRC samples are not valid" severity warning; |
end if; |
end loop; |
else |
wait for 400*CCSDS_RXTX_BENCH_SRRC0_CLK_PERIOD; |
end if; |
bench_sti_srrc0_sam(0) <= '1'; |
wait for CCSDS_RXTX_BENCH_SRRC0_CLK_PERIOD; |
bench_sti_srrc0_sam <= (others => '0'); |
if (CCSDS_RXTX_BENCH_OUTPUT_SIGNALS_ENABLE = true) then |
for i in 0 to 400 loop |
wait for CCSDS_RXTX_BENCH_SRRC0_CLK_PERIOD; |
if (bench_res_srrc0_sam_val = '1') then |
write(samples_hex_output, convert_std_logic_vector_to_hexa_ascii(bench_res_srrc0_sam)); |
writeline(CCSDS_RXTX_BENCH_SRRC0_OUTPUT_HEX_FILE, samples_hex_output); |
else |
report "SRRCP: KO - SRRC samples are not valid" severity warning; |
end if; |
end loop; |
else |
wait for 400*CCSDS_RXTX_BENCH_SRRC0_CLK_PERIOD; |
end if; |
bench_sti_srrc0_sam(CCSDS_RXTX_BENCH_SRRC0_SIG_QUANT_DEPTH-1) <= '1'; |
bench_sti_srrc0_sam(CCSDS_RXTX_BENCH_SRRC0_SIG_QUANT_DEPTH-2 downto 0) <= (others => '0'); |
wait for CCSDS_RXTX_BENCH_SRRC0_CLK_PERIOD; |
bench_sti_srrc0_sam <= (others => '0'); |
if (CCSDS_RXTX_BENCH_OUTPUT_SIGNALS_ENABLE = true) then |
for i in 0 to 400 loop |
wait for CCSDS_RXTX_BENCH_SRRC0_CLK_PERIOD; |
if (bench_res_srrc0_sam_val = '1') then |
write(samples_hex_output, convert_std_logic_vector_to_hexa_ascii(bench_res_srrc0_sam)); |
writeline(CCSDS_RXTX_BENCH_SRRC0_OUTPUT_HEX_FILE, samples_hex_output); |
else |
report "SRRCP: KO - SRRC samples are not valid" severity warning; |
end if; |
end loop; |
else |
wait for 400*CCSDS_RXTX_BENCH_SRRC0_CLK_PERIOD; |
end if; |
bench_sti_srrc0_sam_val <= '0'; |
-- final state tests: |
if (bench_res_srrc0_sam_val = '0') then |
report "SRRCP: OK - Final state - SRRC samples are not valid" severity note; |
else |
report "SRRCP: KO - Final state - SRRC samples are valid" severity warning; |
end if; |
if (bench_res_srrc0_sam = srrc_zero) then |
report "SRRCP: OK - Final state - SRRC samples are null" severity note; |
else |
report "SRRCP: KO - Final state - SRRC samples are not null" severity warning; |
end if; |
report "SRRCP: END SRRC TESTS" severity note; |
-- do nothing |
wait; |
end process; |
--============================================================================= |
-- Begin of resetp |
-- generation of reset pulses |
--============================================================================= |
-- read: |
-- write: bench_sti_rxtx0_wb_rst, bench_sti_crc0_rst, bench_sti_buffer0_rst, bench_sti_framer0_rst |
-- r/w: |
RESETP : process |
begin |
-- let the system free run |
wait for CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION; |
report "RESETP: START RESET SIGNAL TEST" severity note; |
-- send reset signals |
bench_sti_rxtx0_wb_rst <= '1'; |
bench_sti_coder_conv0_rst <= '1'; |
bench_sti_coder_diff0_rst <= '1'; |
bench_sti_crc0_rst <= '1'; |
bench_sti_buffer0_rst <= '1'; |
bench_sti_filter0_rst <= '1'; |
bench_sti_framer0_rst <= '1'; |
bench_sti_lfsr0_rst <= '1'; |
bench_sti_mapper_bits_symbols0_rst <= '1'; |
bench_sti_srrc0_rst <= '1'; |
-- wait for some time |
wait for CCSDS_RXTX_BENCH_START_RESET_SIG_DURATION; |
report "RESETP: END RESET SIGNAL TEST" severity note; |
-- stop reset signals |
bench_sti_rxtx0_wb_rst <= '0'; |
bench_sti_coder_conv0_rst <= '0'; |
bench_sti_coder_diff0_rst <= '0'; |
bench_sti_crc0_rst <= '0'; |
bench_sti_buffer0_rst <= '0'; |
bench_sti_filter0_rst <= '0'; |
bench_sti_framer0_rst <= '0'; |
bench_sti_lfsr0_rst <= '0'; |
bench_sti_mapper_bits_symbols0_rst <= '0'; |
bench_sti_srrc0_rst <= '0'; |
-- do nothing |
wait; |
end process; |
--============================================================================= |
-- Begin of wbrwp |
-- generation of master wb read / write cycles / aligned with clk0 |
--============================================================================= |
-- read: bench_res_rxtx0_wb_ack0, bench_res_rxtx0_wb_err0, bench_res_rxtx0_wb_rty0, bench_sti_rxtx0_wb_random_dat0 |
-- write: bench_sti_rxtx0_wb_adr0, bench_sti_rxtx0_wb_cyc0, bench_sti_rxtx0_wb_stb0, bench_sti_rxtx0_wb_we0, bench_sti_rxtx0_wb_dat0, bench_ena_rxtx0_random_data |
-- r/w: |
WBRWP : process |
variable output_done: boolean := false; |
begin |
-- let the system free run |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2); |
-- default state tests: |
if (bench_res_rxtx0_wb_ack = '0') then |
report "WBRWP: OK - Default state - ACK not enabled" severity note; |
else |
report "WBRWP: OK - Default state - ACK enabled" severity warning; |
end if; |
if (bench_res_rxtx0_wb_err = '0') then |
report "WBRWP: OK - Default state - ERR not enabled" severity note; |
else |
report "WBRWP: OK - Default state - ERR enabled" severity warning; |
end if; |
if (bench_res_rxtx0_wb_rty = '0') then |
report "WBRWP: OK - Default state - RTY not enabled" severity note; |
else |
report "WBRWP: OK - Default state - RTY enabled" severity warning; |
end if; |
-- let the system reset |
wait for (CCSDS_RXTX_BENCH_START_FREE_RUN_DURATION/2 + CCSDS_RXTX_BENCH_START_RESET_SIG_DURATION + CCSDS_RXTX_BENCH_START_WB_WAIT_DURATION); |
-- initial state tests: |
if (bench_res_rxtx0_wb_ack = '0') then |
report "WBRWP: OK - Initial state - ACK not enabled" severity note; |
else |
report "WBRWP: OK - Initial state - ACK enabled" severity warning; |
end if; |
if (bench_res_rxtx0_wb_err = '0') then |
report "WBRWP: OK - Initial state - ERR not enabled" severity note; |
else |
report "WBRWP: OK - Initial state - ERR enabled" severity warning; |
end if; |
if (bench_res_rxtx0_wb_rty = '0') then |
report "WBRWP: OK - Initial state - RTY not enabled" severity note; |
else |
report "WBRWP: OK - Initial state - RTY enabled" severity warning; |
end if; |
-- behaviour tests: |
report "WBRWP: START WISHBONE BUS READ-WRITE TESTS" severity note; |
bench_ena_rxtx0_random_data <= '1'; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
-- start a basic rx read cycle |
bench_sti_rxtx0_wb_we <= '0'; |
bench_sti_rxtx0_wb_adr <= "0000"; |
bench_sti_rxtx0_wb_cyc <= '1'; |
bench_sti_rxtx0_wb_stb <= '1'; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
if (bench_res_rxtx0_wb_ack = '1') and (bench_res_rxtx0_wb_err = '0') and (bench_res_rxtx0_wb_rty = '0') then |
report "WBRWP: OK - RX read cycle success" severity note; |
else |
report "WBRWP: KO - RX read cycle fail" severity warning; |
end if; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
bench_sti_rxtx0_wb_cyc <= '0'; |
bench_sti_rxtx0_wb_stb <= '0'; |
bench_sti_rxtx0_wb_we <= '0'; |
bench_sti_rxtx0_wb_dat <= (others => '0'); |
bench_sti_rxtx0_wb_adr <= "0000"; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD*10; |
-- start an error read cycle |
bench_sti_rxtx0_wb_adr <= "0001"; |
bench_sti_rxtx0_wb_cyc <= '1'; |
bench_sti_rxtx0_wb_stb <= '1'; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
if (bench_res_rxtx0_wb_ack = '0') and (bench_res_rxtx0_wb_err = '1') and (bench_res_rxtx0_wb_rty = '1') then |
report "WBRWP: OK - Error read cycle success" severity note; |
else |
report "WBRWP: KO - Error read cycle fail" severity warning; |
end if; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
bench_sti_rxtx0_wb_cyc <= '0'; |
bench_sti_rxtx0_wb_stb <= '0'; |
bench_sti_rxtx0_wb_we <= '0'; |
bench_sti_rxtx0_wb_dat <= (others => '0'); |
bench_sti_rxtx0_wb_adr <= "0000"; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD*10; |
-- start a basic configuration write cycle -> disable rx |
bench_sti_rxtx0_wb_we <= '1'; |
bench_sti_rxtx0_wb_adr <= "0001"; |
bench_sti_rxtx0_wb_dat <= (others => '0'); |
bench_sti_rxtx0_wb_cyc <= '1'; |
bench_sti_rxtx0_wb_stb <= '1'; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
if (bench_res_rxtx0_wb_ack = '1') and (bench_res_rxtx0_wb_err = '0') and (bench_res_rxtx0_wb_rty = '0') then |
report "WBRWP: OK - RXTX configuration write cycle success (RX disabled)" severity note; |
else |
report "WBRWP: KO - RXTX configuration write cycle fail" severity warning; |
end if; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
bench_sti_rxtx0_wb_cyc <= '0'; |
bench_sti_rxtx0_wb_stb <= '0'; |
bench_sti_rxtx0_wb_we <= '0'; |
bench_sti_rxtx0_wb_dat <= (others => '0'); |
bench_sti_rxtx0_wb_adr <= "0000"; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD*10; |
-- start a basic configuration write cycle -> disable tx |
bench_sti_rxtx0_wb_we <= '1'; |
bench_sti_rxtx0_wb_adr <= "0010"; |
bench_sti_rxtx0_wb_dat <= (others => '0'); |
bench_sti_rxtx0_wb_cyc <= '1'; |
bench_sti_rxtx0_wb_stb <= '1'; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
if (bench_res_rxtx0_wb_ack = '1') and (bench_res_rxtx0_wb_err = '0') and (bench_res_rxtx0_wb_rty = '0') then |
report "WBRWP: OK - RXTX configuration write cycle success (TX disabled)" severity note; |
else |
report "WBRWP: KO - RXTX configuration write cycle fail" severity warning; |
end if; |
bench_sti_rxtx0_wb_cyc <= '0'; |
bench_sti_rxtx0_wb_stb <= '0'; |
bench_sti_rxtx0_wb_we <= '0'; |
bench_sti_rxtx0_wb_dat <= (others => '0'); |
bench_sti_rxtx0_wb_adr <= "0000"; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD*10; |
-- start a basic configuration write cycle -> enable tx + enable internal wb data use for tx |
bench_sti_rxtx0_wb_we <= '1'; |
bench_sti_rxtx0_wb_adr <= "0010"; |
bench_sti_rxtx0_wb_dat <= "00000000000000000000000000000001"; |
bench_sti_rxtx0_wb_cyc <= '1'; |
bench_sti_rxtx0_wb_stb <= '1'; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
if (bench_res_rxtx0_wb_ack = '1') and (bench_res_rxtx0_wb_err = '0') and (bench_res_rxtx0_wb_rty = '0') then |
report "WBRWP: OK - RXTX configuration write cycle success (TX enabled + internal WB data use)" severity note; |
else |
report "WBRWP: KO - RXTX configuration write cycle fail" severity warning; |
end if; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
bench_sti_rxtx0_wb_cyc <= '0'; |
bench_sti_rxtx0_wb_stb <= '0'; |
bench_sti_rxtx0_wb_we <= '0'; |
bench_sti_rxtx0_wb_dat <= (others => '0'); |
bench_sti_rxtx0_wb_adr <= "0000"; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD*10; |
-- start a basic tx write cycle |
bench_sti_rxtx0_wb_we <= '1'; |
bench_sti_rxtx0_wb_adr <= "0000"; |
bench_sti_rxtx0_wb_dat <= bench_sti_rxtx0_wb_random_dat; |
bench_sti_rxtx0_wb_cyc <= '1'; |
bench_sti_rxtx0_wb_stb <= '1'; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
if (bench_res_rxtx0_wb_ack = '1') and (bench_res_rxtx0_wb_err = '0') and (bench_res_rxtx0_wb_rty = '0') then |
report "WBRWP: OK - TX write cycle success" severity note; |
else |
report "WBRWP: KO - TX write cycle fail" severity warning; |
end if; |
bench_sti_rxtx0_wb_cyc <= '0'; |
bench_sti_rxtx0_wb_stb <= '0'; |
bench_sti_rxtx0_wb_we <= '0'; |
bench_sti_rxtx0_wb_dat <= (others => '0'); |
bench_sti_rxtx0_wb_adr <= "0000"; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD*10; |
-- start an error basic tx write cycle (unknown address) |
bench_sti_rxtx0_wb_we <= '1'; |
bench_sti_rxtx0_wb_adr <= "0011"; |
bench_sti_rxtx0_wb_dat <= bench_sti_rxtx0_wb_random_dat; |
bench_sti_rxtx0_wb_cyc <= '1'; |
bench_sti_rxtx0_wb_stb <= '1'; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
if (bench_res_rxtx0_wb_ack = '0') and (bench_res_rxtx0_wb_err = '1') and (bench_res_rxtx0_wb_rty = '1') then |
report "WBRWP: OK - Error write cycle success" severity note; |
else |
report "WBRWP: KO - Error write cycle fail" severity warning; |
end if; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
bench_sti_rxtx0_wb_cyc <= '0'; |
bench_sti_rxtx0_wb_stb <= '0'; |
bench_sti_rxtx0_wb_we <= '0'; |
bench_sti_rxtx0_wb_dat <= (others => '0'); |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD*10; |
-- start many tx write cycle |
for i in 0 to CCSDS_RXTX_BENCH_RXTX0_WB_TX_WRITE_CYCLE_NUMBER-1 loop |
bench_sti_rxtx0_wb_we <= '1'; |
bench_sti_rxtx0_wb_adr <= "0000"; |
bench_sti_rxtx0_wb_dat <= bench_sti_rxtx0_wb_random_dat; |
bench_sti_rxtx0_wb_cyc <= '1'; |
bench_sti_rxtx0_wb_stb <= '1'; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
bench_sti_rxtx0_wb_we <= '0'; |
bench_sti_rxtx0_wb_adr <= "0000"; |
bench_sti_rxtx0_wb_dat <= (others => '0'); |
bench_sti_rxtx0_wb_cyc <= '0'; |
bench_sti_rxtx0_wb_stb <= '0'; |
if (bench_res_rxtx0_wb_ack = '0') or (bench_res_rxtx0_wb_err = '1') or (bench_res_rxtx0_wb_rty = '1') then |
if (CCSDS_RXTX_BENCH_RXTX0_WB_TX_OVERFLOW = true) then |
if (output_done = false) then |
output_done := true; |
report "WBRWP: OK - Many TX write cycles overflow appears after " & integer'image(i) & " WB write cycles (" & integer'image(i*CCSDS_RXTX_BENCH_RXTX0_WB_DATA_BUS_SIZE) & " bits max burst)" severity note; |
end if; |
else |
report "WBRWP: KO - TX write cycle fail: ACK=" & std_logic'image(bench_res_rxtx0_wb_ack) & " ERR=" & std_logic'image(bench_res_rxtx0_wb_err) & " RTY=" & std_logic'image(bench_res_rxtx0_wb_rty) severity warning; |
end if; |
else |
if (i = CCSDS_RXTX_BENCH_RXTX0_WB_TX_WRITE_CYCLE_NUMBER-1) then |
report "WBRWP: OK - Many TX write cycles terminated with success" severity note; |
end if; |
end if; |
if (CCSDS_RXTX_BENCH_RXTX0_WB_TX_OVERFLOW = true) then |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
else |
wait for (CCSDS_RXTX_BENCH_RXTX0_WB_WRITE_CYCLES_MAX-1)*CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD*2 + CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
end if; |
end loop; |
bench_sti_rxtx0_wb_cyc <= '0'; |
bench_sti_rxtx0_wb_stb <= '0'; |
bench_sti_rxtx0_wb_we <= '0'; |
bench_sti_rxtx0_wb_dat <= (others => '0'); |
bench_sti_rxtx0_wb_adr <= "0000"; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD*10; |
-- start a basic configuration write cycle -> enable tx + external serial data activation |
bench_sti_rxtx0_wb_we <= '1'; |
bench_sti_rxtx0_wb_adr <= "0010"; |
bench_sti_rxtx0_wb_dat <= "00000000000000000000000000000011"; |
bench_sti_rxtx0_wb_cyc <= '1'; |
bench_sti_rxtx0_wb_stb <= '1'; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
if (bench_res_rxtx0_wb_ack = '1') and (bench_res_rxtx0_wb_err = '0') and (bench_res_rxtx0_wb_rty = '0') then |
report "WBRWP: OK - Basic configuration write cycle success (TX enabled + external serial data input activated)" severity note; |
else |
report "WBRWP: KO - Basic configuration write cycle fail" severity warning; |
end if; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
bench_sti_rxtx0_wb_cyc <= '0'; |
bench_sti_rxtx0_wb_stb <= '0'; |
bench_sti_rxtx0_wb_we <= '0'; |
bench_sti_rxtx0_wb_dat <= (others => '0'); |
bench_sti_rxtx0_wb_adr <= "0000"; |
wait for CCSDS_RXTX_BENCH_RXTX0_WB_CLK_PERIOD; |
-- final state tests: |
if (bench_res_rxtx0_wb_ack = '0') then |
report "WBRWP: OK - Final state - ACK not enabled" severity note; |
else |
report "WBRWP: OK - Final state - ACK enabled" severity warning; |
end if; |
if (bench_res_rxtx0_wb_err = '0') then |
report "WBRWP: OK - Final state - ERR not enabled" severity note; |
else |
report "WBRWP: OK - Final state - ERR enabled" severity warning; |
end if; |
if (bench_res_rxtx0_wb_rty = '0') then |
report "WBRWP: OK - Final state - RTY not enabled" severity note; |
else |
report "WBRWP: OK - Final state - RTY enabled" severity warning; |
end if; |
report "WBRWP: END WISHBONE BUS READ-WRITE TESTS" severity note; |
-- bench_ena_rxtx0_random_data <= '0'; |
wait; |
end process; |
end behaviour; |
--============================================================================= |
-- architecture end |
--============================================================================= |
/ccsds_rxtx_buffer.vhd
0,0 → 1,141
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_rxtx_buffer |
---- Version: 1.0.0 |
---- Description: |
---- FIFO circular buffer |
---- Input: 1 clk / [STORE: dat_val_i <= '1' / dat_i <= "STOREDDATA" ] / [READ: nxt_i <= '1'] |
---- Timing requirements: 1 clock cycle |
---- Output: [READ: dat_val_o <= "1" / dat_o <= "STOREDDATA"] |
---- Ressources requirements: CCSDS_RXTX_BUFFER_DATA_BUS_SIZE*(CCSDS_RXTX_BUFFER_SIZE+1) + 2*|log(CCSDS_RXTX_BUFFER_SIZE-1)/log(2)| + 2 + 3 + CCSDS_RXTX_BUFFER_DATA_BUS_SIZE registers |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/02/27: initial release |
---- 2016/10/20: major corrections and optimizations |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary rxtx buffer inputs and outputs |
--============================================================================= |
entity ccsds_rxtx_buffer is |
generic( |
constant CCSDS_RXTX_BUFFER_DATA_BUS_SIZE : integer; -- in bits |
constant CCSDS_RXTX_BUFFER_SIZE : integer |
); |
port( |
-- inputs |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_RXTX_BUFFER_DATA_BUS_SIZE-1 downto 0); |
dat_nxt_i: in std_logic; |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
-- outputs |
buf_emp_o: out std_logic; |
buf_ful_o: out std_logic; |
dat_o: out std_logic_vector(CCSDS_RXTX_BUFFER_DATA_BUS_SIZE-1 downto 0); |
dat_val_o: out std_logic |
); |
end ccsds_rxtx_buffer; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture rtl of ccsds_rxtx_buffer is |
|
-- interconnection signals |
type buffer_array is array (CCSDS_RXTX_BUFFER_SIZE downto 0) of std_logic_vector(CCSDS_RXTX_BUFFER_DATA_BUS_SIZE-1 downto 0); |
signal buffer_data: buffer_array := (others => (others => '0')); |
signal buffer_read_pos: integer range 0 to CCSDS_RXTX_BUFFER_SIZE := 0; |
signal buffer_write_pos: integer range 0 to CCSDS_RXTX_BUFFER_SIZE := 0; |
|
-- components instanciation and mapping |
begin |
|
-- internal processing |
|
--============================================================================= |
-- Begin of bufferpullp |
-- Read data from buffer |
--============================================================================= |
-- read: nxt_dat_i, rst_i, buffer_write_pos, buffer_data |
-- write: dat_o, dat_val_o, buf_emp_o |
-- r/w: buffer_read_pos |
BUFFERPULLP : process (clk_i) |
begin |
if rising_edge(clk_i) then |
if (rst_i = '1') then |
buf_emp_o <= '1'; |
buffer_read_pos <= 0; |
dat_o <= (others => '0'); |
dat_val_o <= '0'; |
else |
if (buffer_read_pos = buffer_write_pos) then |
buf_emp_o <= '1'; |
dat_val_o <= '0'; |
else |
buf_emp_o <= '0'; |
if (dat_nxt_i = '1') then |
dat_val_o <= '1'; |
dat_o <= buffer_data(buffer_read_pos); |
if (buffer_read_pos < CCSDS_RXTX_BUFFER_SIZE) then |
buffer_read_pos <= (buffer_read_pos + 1); |
else |
buffer_read_pos <= 0; |
end if; |
else |
dat_val_o <= '0'; |
end if; |
end if; |
end if; |
end if; |
end process; |
--============================================================================= |
-- Begin of bufferpushp |
-- Store valid input data in buffer |
--============================================================================= |
-- read: dat_i, dat_val_i, buffer_read_pos, rst_i |
-- write: buffer_data, buf_ful_o |
-- r/w: buffer_write_pos |
BUFFERPUSH : process (clk_i) |
begin |
if rising_edge(clk_i) then |
if (rst_i = '1') then |
-- buffer_data <= (others => (others => '0')); |
buf_ful_o <= '0'; |
buffer_write_pos <= 0; |
else |
if (buffer_write_pos < CCSDS_RXTX_BUFFER_SIZE) then |
if (buffer_read_pos = (buffer_write_pos+1)) then |
buf_ful_o <= '1'; |
else |
buf_ful_o <= '0'; |
if (dat_val_i = '1') then |
buffer_data(buffer_write_pos) <= dat_i; |
buffer_write_pos <= (buffer_write_pos + 1); |
end if; |
end if; |
else |
if (buffer_read_pos = 0) then |
buf_ful_o <= '1'; |
else |
buf_ful_o <= '0'; |
if (dat_val_i = '1') then |
buffer_data(buffer_write_pos) <= dat_i; |
buffer_write_pos <= 0; |
end if; |
end if; |
end if; |
end if; |
end if; |
end process; |
end rtl; |
/ccsds_rxtx_clock_divider.vhd
0,0 → 1,89
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_rxtx_clock_divider |
---- Version: 1.0.0 |
---- Description: |
---- Generate output clock = input clock / divider |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/11/05: initial release |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary tx clock generator inputs and outputs |
--============================================================================= |
entity ccsds_rxtx_clock_divider is |
generic( |
constant CCSDS_RXTX_CLOCK_DIVIDER: integer range 1 to 4096 |
); |
port( |
-- inputs |
clk_i: in std_logic; |
rst_i: in std_logic; |
-- outputs |
clk_o: out std_logic |
); |
end ccsds_rxtx_clock_divider; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture structure of ccsds_rxtx_clock_divider is |
-- internal constants |
-- internal variable signals |
-- components instanciation and mapping |
begin |
-- presynthesis checks |
CHKCLKDIV0: if (CCSDS_RXTX_CLOCK_DIVIDER mod 2 /= 0) and (CCSDS_RXTX_CLOCK_DIVIDER /= 1) generate |
process |
begin |
report "ERROR: CLOCK DIVIDER MUST BE A MULTIPLE OF 2 OR 1" severity failure; |
wait; |
end process; |
end generate CHKCLKDIV0; |
-- internal processing |
CLOCKDIVIDER1P: if (CCSDS_RXTX_CLOCK_DIVIDER = 1) generate |
clk_o <= clk_i and (not rst_i); |
end generate CLOCKDIVIDER1P; |
CLOCKDIVIDERNP: if (CCSDS_RXTX_CLOCK_DIVIDER /= 1) generate |
--============================================================================= |
-- Begin of clockdividerp |
-- Clock divider |
--============================================================================= |
-- read: rst_i |
-- write: clk_o |
-- r/w: |
CLOCKDIVIDERP : process (clk_i, rst_i) |
-- variables instantiation |
variable counter: integer range 0 to CCSDS_RXTX_CLOCK_DIVIDER/2-1 := CCSDS_RXTX_CLOCK_DIVIDER/2-1; |
variable clock_state: std_logic := '1'; |
begin |
if (rst_i = '1') then |
clk_o <= '0'; |
clock_state := '1'; |
counter := CCSDS_RXTX_CLOCK_DIVIDER/2-1; |
else |
-- on each clock rising edge |
if rising_edge(clk_i) then |
clk_o <= clock_state; |
if (counter = 0) then |
clock_state := clock_state xor '1'; |
counter := CCSDS_RXTX_CLOCK_DIVIDER/2-1; |
else |
counter := counter-1; |
end if; |
end if; |
end if; |
end process; |
end generate CLOCKDIVIDERNP; |
end structure; |
/ccsds_rxtx_constants.vhd
0,0 → 1,20
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_rxtx_constants |
---- Version: 1.0.0 |
---- Description: |
---- TO BE DONE |
------------------------------- |
---- Author(s): |
---- Guillaume Rembert |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2015/11/17: initial release |
------------------------------- |
|
package ccsds_rxtx_constants is |
constant RXTX_CST: integer := 1; -- DUMMY USELESS CONSTANT |
end ccsds_rxtx_constants; |
/ccsds_rxtx_crc.vhd
0,0 → 1,342
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_rxtx_crc |
---- Version: 1.0.0 |
---- Description: |
---- CRC computation core |
---- Input: 1 clk / nxt_dat_i <= '1' / dat_i <= "CRCCOMPUTEDDATA" / [pad_dat_val_i <= '1' / pad_dat_i <= "PADDINGDATA"] |
---- Timing requirements: (CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8+1 clock cycles for valid output CRC |
---- Output: dat_val_o <= "1" / dat_o <= "CRCCOMPUTEDDATA" / crc_o <= "CRCCOMPUTED" |
---- Ressources requirements: data computed registers + crc registers + padding data registers + busy state registers + data_valid state registers + crc data pointer registers = (CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH*2)*8 + 2 + |log(CCSDS_RXTX_CRC_DATA_LENGTH-1)/log(2)| + 1 registers |
--TODO: ressources with inversions |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/10/18: initial release |
---- 2016/10/25: external padding data mode |
---- 2016/10/30: ressources usage optimization |
------------------------------- |
--TODO: Implement DIRECT computation? |
--TODO: CRC LENGTH not being multiple of Byte |
|
-- CRC reference and explanations: |
-- http://www.ross.net/crc/download/crc_v3.txt |
|
-- Online data converters: |
-- http://www.asciitohex.com/ |
|
-- Online CRC computers: |
-- http://www.sunshine2k.de/coding/javascript/crc/crc_js.html |
-- http://www.zorc.breitbandkatze.de/crc.html |
-- NB: use nondirect configuration |
|
-- COMMON STANDARDS CONFIGURATIONS: |
-- http://reveng.sourceforge.net/crc-catalogue/ |
-- WARNING: some check values found there are linked to direct computation / cf: http://srecord.sourceforge.net/crc16-ccitt.html |
-------------------- |
-- Check value: x"313233343536373839" <=> 123456789/ASCII |
-------------------- |
-- CRC-8/DVB-S2 |
-- Width = 8 bits |
-- Truncated polynomial = 0xd5 |
-- Initial value = 0x00 |
-- Input data reflected: false |
-- Output CRC reflected: false |
-- XOR final = 0x00 |
-- Check = 0xbc |
-------------------- |
-- CRC-8/ITU/ATM |
-- Width = 8 bits |
-- Truncated polynomial = 0x07 |
-- Initial value = 0x00 |
-- Input data reflected: false |
-- Output CRC reflected: false |
-- XOR final = 0x55 |
-- Check = 0xa1 |
-------------------- |
-- CRC-8/LTE |
-- Width = 8 bits |
-- Truncated polynomial = 0x9b |
-- Initial value = 0x00 |
-- Input data reflected: false |
-- Output CRC reflected: false |
-- XOR final = 0x00 |
-- Check = 0xea |
-------------------- |
-- CRC-16/CCSDS/CCITT-FALSE |
-- Width = 16 bits |
-- Truncated polynomial = 0x1021 |
-- Initial value = 0xffff |
-- Input data reflected: false |
-- Output CRC reflected: false |
-- XOR final = 0x0000 |
-- Check = 0xe5cc |
-------------------- |
-- CRC-16/LTE |
-- Width = 16 bits |
-- Truncated polynomial = 0x1021 |
-- Initial value = 0x0000 |
-- Input data reflected: false |
-- Output CRC reflected: false |
-- XOR final = 0x0000 |
-- Check = 0x31c3 |
-------------------- |
-- CRC-16/CCITT-TRUE/KERMIT |
-- Width = 16 bits |
-- Truncated polynomial = 0x1021 |
-- Initial value = 0x0000 |
-- Input data reflected: true |
-- Output CRC reflected: true |
-- XOR final = 0x0000 |
-- Check = 0x2189 |
-------------------- |
-- CRC-16/UMTS |
-- Width = 16 bits |
-- Truncated polynomial = 0x8005 |
-- Initial value = 0x0000 |
-- Input data reflected: false |
-- Output CRC reflected: false |
-- XOR final = 0x0000 |
-- Check = 0xfee8 |
-------------------- |
-- CRC-16/X-25 |
-- Width = 16 bits |
-- Truncated polynomial = 0x1021 |
-- Initial value = 0xffff |
-- Input data reflected: true |
-- Output CRC reflected: true |
-- XOR final = 0xffff |
-- Check = 0x2e5d |
-------------------- |
-- CRC-32/ADCCP |
-- Width = 32 bits |
-- Truncated polynomial = 0x04c11db7 |
-- Initial value = 0xffffffff |
-- Input data reflected: true |
-- Output CRC reflected: true |
-- XOR final = 0xffffffff |
-- Check = 0x22896b0a |
---------------- |
-- CRC-32/BZIP2 |
-- Width = 32 bits |
-- Truncated polynomial = 0x04c11db7 |
-- Initial value = 0xffffffff |
-- Input data reflected: false |
-- Output CRC reflected: false |
-- XOR final = 0xffffffff |
-- Check = 0xfc891918 |
---------------- |
-- CRC-32/MPEG-2 |
-- Width = 32 bits |
-- Truncated polynomial = 0x04c11db7 |
-- Initial value = 0xffffffff |
-- Input data reflected: false |
-- Output CRC reflected: false |
-- XOR final = 0x00000000 |
-- Check = 0x373C5870 |
---------------- |
-- CRC-32/POSIX |
-- Width = 32 bits |
-- Truncated polynomial = 0x04c11db7 |
-- Initial value = 0x00000000 |
-- Input data reflected: false |
-- Output CRC reflected: false |
-- XOR final = 0xffffffff |
-- Check = 0x765e7680 |
---------------- |
-- CRC-64/WE |
-- Width = 64 bits |
-- Truncated polynomial = 0x42f0e1eba9ea3693 |
-- Initial value = 0xffffffffffffffff |
-- Input data reflected: false |
-- Output CRC reflected: false |
-- XOR final = 0xffffffffffffffff |
-- Check = 0xd2c7a4d6f38185a4 |
---------------- |
-- CRC-64/XZ |
-- Width = 64 bits |
-- Truncated polynomial = 0x42f0e1eba9ea3693 |
-- Initial value = 0xffffffffffffffff |
-- Input data reflected: true |
-- Output CRC reflected: true |
-- XOR final = 0xffffffffffffffff |
-- Check = 0xecf36dfb73a6edf7 |
---------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
library work; |
use work.ccsds_rxtx_functions.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary rxtx crc inputs and outputs |
--============================================================================= |
entity ccsds_rxtx_crc is |
generic( |
constant CCSDS_RXTX_CRC_DATA_LENGTH: integer := 2; -- Data length - in Bytes |
constant CCSDS_RXTX_CRC_FINAL_XOR: std_logic_vector := x"0000"; -- Final XOR mask (0x0000 <=> No XOR) |
constant CCSDS_RXTX_CRC_INPUT_BYTES_REFLECTED: boolean := false; -- Reflect input byte by byte (used by standards) |
constant CCSDS_RXTX_CRC_INPUT_REFLECTED: boolean := false; -- Reflect input on overall data (not currently used by standards) / WARNING - take over input bytes reflected parameter if activated |
constant CCSDS_RXTX_CRC_LENGTH: integer := 2; -- CRC value depth - in Bytes |
constant CCSDS_RXTX_CRC_OUTPUT_REFLECTED: boolean := false; -- Reflect output |
constant CCSDS_RXTX_CRC_POLYNOMIAL: std_logic_vector := x"1021"; -- Truncated polynomial / MSB <=> lower polynome (needs to be '1') |
constant CCSDS_RXTX_CRC_POLYNOMIAL_REFLECTED: boolean := false; -- Reflect polynomial |
constant CCSDS_RXTX_CRC_SEED: std_logic_vector := x"FFFF" -- Initial value from register |
); |
port( |
-- inputs |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_RXTX_CRC_DATA_LENGTH*8-1 downto 0); |
nxt_i: in std_logic; |
pad_dat_i: in std_logic_vector(CCSDS_RXTX_CRC_LENGTH*8-1 downto 0); |
pad_dat_val_i: in std_logic; |
rst_i: in std_logic; |
-- outputs |
bus_o: out std_logic; |
crc_o: out std_logic_vector(CCSDS_RXTX_CRC_LENGTH*8-1 downto 0); |
dat_o: out std_logic_vector(CCSDS_RXTX_CRC_DATA_LENGTH*8-1 downto 0); |
dat_val_o: out std_logic |
); |
end ccsds_rxtx_crc; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture rtl of ccsds_rxtx_crc is |
|
-- internal variable signals |
signal crc_busy: std_logic := '0'; |
signal crc_data: std_logic_vector((CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8-1 downto 0) := (others => '0'); |
signal crc_memory: std_logic_vector(CCSDS_RXTX_CRC_LENGTH*8-1 downto 0) := CCSDS_RXTX_CRC_SEED; |
|
-- components instanciation and mapping |
begin |
bus_o <= crc_busy; |
crc_o <= crc_memory; |
dat_o <= crc_data((CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8-1 downto CCSDS_RXTX_CRC_LENGTH*8); |
-- presynthesis checks |
CHKCRCP0 : if CCSDS_RXTX_CRC_SEED'length /= CCSDS_RXTX_CRC_LENGTH*8 generate |
process |
begin |
report "ERROR: CRC SEED VALUE LENGTH MUST BE EQUAL TO CRC LENGTH" severity failure; |
wait; |
end process; |
end generate CHKCRCP0; |
CHKCRCP1 : if CCSDS_RXTX_CRC_POLYNOMIAL'length /= CCSDS_RXTX_CRC_LENGTH*8 generate |
process |
begin |
report "ERROR: CRC POLYNOMIAL LENGTH MUST BE EQUAL TO CRC LENGTH (SHORTENED VERSION / DON'T PUT MANDATORY HIGHER POLYNOME '1')" severity failure; |
wait; |
end process; |
end generate CHKCRCP1; |
CHKCRCP2 : if CCSDS_RXTX_CRC_POLYNOMIAL(CCSDS_RXTX_CRC_LENGTH*8-1) = '0' generate |
process |
begin |
report "ERROR: CRC POLYNOMIAL MSB MUST BE EQUAL TO '1': " & std_logic'image(CCSDS_RXTX_CRC_POLYNOMIAL(CCSDS_RXTX_CRC_LENGTH*8-1)) severity failure; |
wait; |
end process; |
end generate CHKCRCP2; |
CHKCRCP3 : if CCSDS_RXTX_CRC_INPUT_BYTES_REFLECTED = true and CCSDS_RXTX_CRC_INPUT_REFLECTED = true generate |
process |
begin |
report "ERROR: CRC INPUT DATA REFLECTION CANNOT BE DONE SIMULTANEOUSLY ON OVERALL DATA AND BYTE BY BYTE" severity failure; |
wait; |
end process; |
end generate CHKCRCP3; |
-- internal processing |
|
--============================================================================= |
-- Begin of crcp |
-- Compute CRC based on input data |
--============================================================================= |
-- read: rst_i, nxt_i, pad_dat_i, pad_dat_val_i |
-- write: dat_val_o, crc_busy, crc_memory |
-- r/w: crc_data |
CRCP: process (clk_i) |
variable crc_data_pointer: integer range -2 to ((CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8-1) := -2; |
begin |
-- on each clock rising edge |
if rising_edge(clk_i) then |
-- reset signal received |
if (rst_i = '1') then |
crc_busy <= '0'; |
dat_val_o <= '0'; |
-- crc_memory <= CCSDS_RXTX_CRC_SEED; |
-- crc_data <= (others => '0'); |
crc_data_pointer := -2; |
else |
case crc_data_pointer is |
-- no current crc under computation |
when -2 => |
dat_val_o <= '0'; |
-- CRC computation required and |
if (nxt_i = '1') then |
crc_busy <= '1'; |
crc_memory <= CCSDS_RXTX_CRC_SEED; |
crc_data_pointer := (CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8-1; |
if (CCSDS_RXTX_CRC_INPUT_REFLECTED) then |
crc_data((CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8-1 downto CCSDS_RXTX_CRC_LENGTH*8) <= reverse_std_logic_vector(dat_i); |
elsif (CCSDS_RXTX_CRC_INPUT_BYTES_REFLECTED) then |
for data_pointer in CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH-1 downto CCSDS_RXTX_CRC_LENGTH loop |
crc_data((data_pointer+1)*8-1 downto data_pointer*8) <= reverse_std_logic_vector(dat_i(((data_pointer+1-CCSDS_RXTX_CRC_LENGTH)*8-1) downto (data_pointer-CCSDS_RXTX_CRC_LENGTH)*8)); |
end loop; |
else |
crc_data((CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8-1 downto CCSDS_RXTX_CRC_LENGTH*8) <= dat_i; |
end if; |
if (pad_dat_val_i = '1') then |
if (CCSDS_RXTX_CRC_OUTPUT_REFLECTED) then |
crc_data(CCSDS_RXTX_CRC_LENGTH*8-1 downto 0) <= reverse_std_logic_vector(pad_dat_i); |
else |
crc_data(CCSDS_RXTX_CRC_LENGTH*8-1 downto 0) <= pad_dat_i; |
end if; |
else |
crc_data(CCSDS_RXTX_CRC_LENGTH*8-1 downto 0) <= (others => '0'); |
end if; |
else |
-- nothing to be done |
crc_busy <= '0'; |
end if; |
-- CRC is computed |
when -1 => |
crc_busy <= '0'; |
dat_val_o <= '1'; |
crc_data_pointer := -2; |
if (CCSDS_RXTX_CRC_OUTPUT_REFLECTED) then |
crc_memory <= reverse_std_logic_vector(crc_memory xor CCSDS_RXTX_CRC_FINAL_XOR); |
else |
crc_memory <= (crc_memory xor CCSDS_RXTX_CRC_FINAL_XOR); |
end if; |
if (CCSDS_RXTX_CRC_INPUT_REFLECTED) then |
crc_data((CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8-1 downto CCSDS_RXTX_CRC_LENGTH*8) <= reverse_std_logic_vector(crc_data((CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH)*8-1 downto CCSDS_RXTX_CRC_LENGTH*8)); |
elsif (CCSDS_RXTX_CRC_INPUT_BYTES_REFLECTED) then |
for data_pointer in CCSDS_RXTX_CRC_DATA_LENGTH+CCSDS_RXTX_CRC_LENGTH-1 downto CCSDS_RXTX_CRC_LENGTH loop |
crc_data(((data_pointer+1)*8-1) downto data_pointer*8) <= reverse_std_logic_vector(crc_data(((data_pointer+1)*8-1) downto data_pointer*8)); |
end loop; |
end if; |
-- Computing CRC |
when others => |
crc_busy <= '1'; |
dat_val_o <= '0'; |
-- MSB = 1 / register shifted output bit will be '1' |
if (crc_memory(CCSDS_RXTX_CRC_LENGTH*8-1) = '1') then |
if (CCSDS_RXTX_CRC_POLYNOMIAL_REFLECTED) then |
crc_memory <= (std_logic_vector(resize(unsigned(crc_memory),CCSDS_RXTX_CRC_LENGTH*8-1)) & crc_data(crc_data_pointer)) xor reverse_std_logic_vector(CCSDS_RXTX_CRC_POLYNOMIAL); |
else |
crc_memory <= (std_logic_vector(resize(unsigned(crc_memory),CCSDS_RXTX_CRC_LENGTH*8-1)) & crc_data(crc_data_pointer)) xor CCSDS_RXTX_CRC_POLYNOMIAL; |
end if; |
else |
crc_memory <= (std_logic_vector(resize(unsigned(crc_memory),CCSDS_RXTX_CRC_LENGTH*8-1)) & crc_data(crc_data_pointer)); |
end if; |
crc_data_pointer := crc_data_pointer - 1; |
end case; |
end if; |
end if; |
end process; |
end rtl; |
/ccsds_rxtx_functions.vhd
0,0 → 1,135
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_rxtx_functions |
---- Version: 1.0.0 |
---- Description: |
---- TO BE DONE |
------------------------------- |
---- Author(s): |
---- Guillaume Rembert |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2015/12/28: initial release |
---- 2016/10/20: added reverse_std_logic_vector function + rework sim_generate_random_std_logic_vector for > 32 bits vectors |
---- 2016/11/17: added convert_boolean_to_std_logic function |
---- 2017/01/15: added convert_std_logic_vector_array_to_std_logic_vector |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use ieee.math_real.all; |
use work.ccsds_rxtx_types.all; |
|
package ccsds_rxtx_functions is |
-- synthetizable functions |
function convert_boolean_to_std_logic(input: in boolean) return std_logic; |
function convert_std_logic_vector_array_to_std_logic_vector(std_logic_vector_array_in: in std_logic_vector_array; current_row: in integer) return std_logic_vector; |
function reverse_std_logic_vector (input: in std_logic_vector) return std_logic_vector; |
-- simulation / testbench only functions |
function convert_std_logic_vector_to_hexa_ascii(input: in std_logic_vector) return string; |
procedure sim_generate_random_std_logic_vector(vector_size : in integer; seed1 : inout positive; seed2 : inout positive; result : out std_logic_vector); |
end ccsds_rxtx_functions; |
|
package body ccsds_rxtx_functions is |
|
function convert_boolean_to_std_logic(input: in boolean) return std_logic is |
begin |
if (input = true) then |
return '1'; |
else |
return '0'; |
end if; |
end convert_boolean_to_std_logic; |
|
function convert_std_logic_vector_array_to_std_logic_vector(std_logic_vector_array_in: in std_logic_vector_array; current_row: in integer) return std_logic_vector is |
variable result: std_logic_vector(std_logic_vector_array_in'range(2)); |
begin |
for i in std_logic_vector_array_in'range(2) loop |
result(i) := std_logic_vector_array_in(current_row, i); |
-- report "Read: " & std_logic'image(std_logic_vector_array_in(current_row, i)) severity note; |
end loop; |
return result; |
end; |
|
function reverse_std_logic_vector (input: in std_logic_vector) return std_logic_vector is |
variable result: std_logic_vector(input'range); |
alias output: std_logic_vector(input'REVERSE_RANGE) is input; |
begin |
for vector_pointer in output'range loop |
result(vector_pointer) := output(vector_pointer); |
end loop; |
return result; |
end; |
|
function convert_std_logic_vector_to_hexa_ascii(input: in std_logic_vector) return string is |
constant words_number: integer := input'length/4; |
variable result: string(words_number-1 downto 0); |
variable word: std_logic_vector(3 downto 0); |
begin |
for vector_word_pointer in words_number-1 downto 0 loop |
word := input((vector_word_pointer+1)*4-1 downto vector_word_pointer*4); |
case word is |
when "0000" => |
result(vector_word_pointer) := '0'; |
when "0001" => |
result(vector_word_pointer) := '1'; |
when "0010" => |
result(vector_word_pointer) := '2'; |
when "0011" => |
result(vector_word_pointer) := '3'; |
when "0100" => |
result(vector_word_pointer) := '4'; |
when "0101" => |
result(vector_word_pointer) := '5'; |
when "0110" => |
result(vector_word_pointer) := '6'; |
when "0111" => |
result(vector_word_pointer) := '7'; |
when "1000" => |
result(vector_word_pointer) := '8'; |
when "1001" => |
result(vector_word_pointer) := '9'; |
when "1010" => |
result(vector_word_pointer) := 'a'; |
when "1011" => |
result(vector_word_pointer) := 'b'; |
when "1100" => |
result(vector_word_pointer) := 'c'; |
when "1101" => |
result(vector_word_pointer) := 'd'; |
when "1110" => |
result(vector_word_pointer) := 'e'; |
when "1111" => |
result(vector_word_pointer) := 'f'; |
when others => |
result(vector_word_pointer) := '?'; |
end case; |
-- report "Converted " & integer'image(to_integer(resize(unsigned(word),16))) & " to " & result(vector_word_pointer) severity note; |
end loop; |
return result; |
end; |
|
procedure sim_generate_random_std_logic_vector(vector_size : in integer; seed1 : inout positive; seed2 : inout positive; result : out std_logic_vector) is |
variable rand: real := 0.0; |
variable temp: std_logic_vector(31 downto 0); |
begin |
if (vector_size < 32) then |
uniform(seed1, seed2, rand); |
rand := rand*(2**(real(vector_size))-1.0); |
result := std_logic_vector(to_unsigned(integer(rand),vector_size)); |
else |
uniform(seed1, seed2, rand); |
for vector_pointer in 0 to vector_size-1 loop |
uniform(seed1, seed2, rand); |
rand := rand*(2**(real(31))-1.0); |
temp := std_logic_vector(to_unsigned(integer(rand),32)); |
result(vector_pointer) := temp(0); |
end loop; |
end if; |
end sim_generate_random_std_logic_vector; |
end ccsds_rxtx_functions; |
/ccsds_rxtx_lfsr.vhd
0,0 → 1,160
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_rxtx_lfsr |
---- Version: 1.0.0 |
---- Description: |
---- Linear Feedback Shift Register |
---- Input: none |
---- Timing requirements: CCSDS_RXTX_LFSR_DATA_BUS_SIZE+1 clock cycles for valid output data |
---- Output: dat_val_o <= "1" / dat_o <= "LFSRSEQUENCE" |
---- Ressources requirements: TODO |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/11/05: initial release |
------------------------------- |
-- Test ressources: |
-- GNURADIO GLFSR block |
|
-- CCSDS parameters |
-- Width = 8 |
-- Mode = Fibonacci ('0') |
-- Polynomial = x"A9" |
-- Seed = x"FF" |
-- Result = "1111111101001000000011101100000010011010" |
|
-- Width = 8 |
-- Mode = Galois ('1') |
-- Polynomial = x"A9" |
-- Seed = x"FF" |
-- Result = "101001011011000001011000110110" |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary tx randomizer inputs and outputs |
--============================================================================= |
entity ccsds_rxtx_lfsr is |
generic( |
constant CCSDS_RXTX_LFSR_DATA_BUS_SIZE: integer; -- in bits |
constant CCSDS_RXTX_LFSR_MEMORY_SIZE: integer range 2 to 256 := 8; -- in bits |
constant CCSDS_RXTX_LFSR_MODE: std_logic := '0'; -- 0: Fibonacci / 1: Galois |
constant CCSDS_RXTX_LFSR_POLYNOMIAL: std_logic_vector := x"A9"; -- Polynomial / MSB <=> lower polynome (needs to be '1') |
constant CCSDS_RXTX_LFSR_SEED: std_logic_vector := x"FF" -- Initial Value |
); |
port( |
-- inputs |
clk_i: in std_logic; |
rst_i: in std_logic; |
-- outputs |
dat_o: out std_logic_vector(CCSDS_RXTX_LFSR_DATA_BUS_SIZE-1 downto 0); |
dat_val_o: out std_logic |
); |
end ccsds_rxtx_lfsr; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture structure of ccsds_rxtx_lfsr is |
|
-- internal constants |
-- internal variable signals |
signal lfsr_memory: std_logic_vector(CCSDS_RXTX_LFSR_MEMORY_SIZE-1 downto 0) := CCSDS_RXTX_LFSR_SEED; |
-- components instanciation and mapping |
begin |
|
-- presynthesis checks |
CHKLFSRP0 : if CCSDS_RXTX_LFSR_POLYNOMIAL'length /= CCSDS_RXTX_LFSR_MEMORY_SIZE generate |
process |
begin |
report "ERROR: LFSR_POLYNOMIAL LENGTH MUST BE EQUAL TO MEMORY SIZE (SHORTENED VERSION / DON'T PUT MANDATORY HIGHER POLYNOME '1')" severity failure; |
wait; |
end process; |
end generate CHKLFSRP0; |
CHKLFSRP1 : if CCSDS_RXTX_LFSR_MEMORY_SIZE <= 1 generate |
process |
begin |
report "ERROR: LFSR_MEMORY_SIZE MUST BE BIGGER THAN 1" severity failure; |
wait; |
end process; |
end generate CHKLFSRP1; |
CHKLFSRP2 : if CCSDS_RXTX_LFSR_SEED'length /= CCSDS_RXTX_LFSR_MEMORY_SIZE generate |
process |
begin |
report "ERROR: LFSR_SEED LENGTH MUST BE EQUAL TO LFSR_MEMORY_SIZE" severity failure; |
wait; |
end process; |
end generate CHKLFSRP2; |
CHKLFSRP3 : if CCSDS_RXTX_LFSR_POLYNOMIAL(CCSDS_RXTX_LFSR_MEMORY_SIZE-1) = '0' generate |
process |
begin |
report "ERROR: LFSR POLYNOMIAL MSB MUST BE EQUAL TO 1" severity failure; |
wait; |
end process; |
end generate CHKLFSRP3; |
|
-- internal processing |
--============================================================================= |
-- Begin of crcp |
-- Compute CRC based on input data |
--============================================================================= |
-- read: rst_i |
-- write: dat_o, dat_val_o |
-- r/w: lfsr_memory |
LFSRP: process (clk_i) |
variable output_pointer: integer range -1 to (CCSDS_RXTX_LFSR_DATA_BUS_SIZE-1) := CCSDS_RXTX_LFSR_DATA_BUS_SIZE-1; |
variable feedback_register: std_logic := '0'; |
begin |
-- on each clock rising edge |
if rising_edge(clk_i) then |
-- reset signal received |
if (rst_i = '1') then |
lfsr_memory <= CCSDS_RXTX_LFSR_SEED; |
dat_o <= (others => '0'); |
dat_val_o <= '0'; |
output_pointer := CCSDS_RXTX_LFSR_DATA_BUS_SIZE-1; |
feedback_register := '0'; |
else |
-- generation is finished |
if (output_pointer = -1) then |
dat_val_o <= '1'; |
-- generating sequence |
else |
dat_val_o <= '0'; |
-- Fibonacci |
if (CCSDS_RXTX_LFSR_MODE = '0') then |
dat_o(output_pointer) <= lfsr_memory(CCSDS_RXTX_LFSR_MEMORY_SIZE-1); |
output_pointer := output_pointer - 1; |
feedback_register := lfsr_memory(CCSDS_RXTX_LFSR_MEMORY_SIZE-1); |
for i in 0 to CCSDS_RXTX_LFSR_MEMORY_SIZE-2 loop |
if (CCSDS_RXTX_LFSR_POLYNOMIAL(i) = '1') then |
feedback_register := feedback_register xor lfsr_memory(i); |
end if; |
end loop; |
lfsr_memory <= std_logic_vector(resize(unsigned(lfsr_memory),CCSDS_RXTX_LFSR_MEMORY_SIZE-1)) & feedback_register; |
-- Galois |
else |
dat_o(output_pointer) <= lfsr_memory(CCSDS_RXTX_LFSR_MEMORY_SIZE-1); |
output_pointer := output_pointer - 1; |
lfsr_memory(0) <= lfsr_memory(CCSDS_RXTX_LFSR_MEMORY_SIZE-1); |
for i in 1 to CCSDS_RXTX_LFSR_MEMORY_SIZE-1 loop |
if (CCSDS_RXTX_LFSR_POLYNOMIAL(i) = '1') then |
lfsr_memory(i) <= lfsr_memory(i-1) xor lfsr_memory(CCSDS_RXTX_LFSR_MEMORY_SIZE-1); |
else |
lfsr_memory(i) <= lfsr_memory(i-1); |
end if; |
end loop; |
end if; |
end if; |
end if; |
end if; |
end process; |
end structure; |
/ccsds_rxtx_oversampler.vhd
0,0 → 1,113
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_rxtx_oversampler |
---- Version: 1.0.0 |
---- Description: |
---- Insert OSR-1 '0' between symbols |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/11/06: initial release |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary rxtx oversampler inputs and outputs |
--============================================================================= |
entity ccsds_rxtx_oversampler is |
generic( |
constant CCSDS_RXTX_OVERSAMPLER_OVERSAMPLING_RATIO: integer := 4; |
constant CCSDS_RXTX_OVERSAMPLER_SYMBOL_DEPHASING: boolean := false; |
constant CCSDS_RXTX_OVERSAMPLER_SIG_QUANT_DEPTH: integer |
); |
port( |
-- inputs |
clk_i: in std_logic; |
rst_i: in std_logic; |
sam_i: in std_logic_vector(CCSDS_RXTX_OVERSAMPLER_SIG_QUANT_DEPTH-1 downto 0); |
sam_val_i: in std_logic; |
-- outputs |
sam_o: out std_logic_vector(CCSDS_RXTX_OVERSAMPLER_SIG_QUANT_DEPTH-1 downto 0); |
sam_val_o: out std_logic |
); |
end ccsds_rxtx_oversampler; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture structure of ccsds_rxtx_oversampler is |
-- internal constants |
-- internal variable signals |
-- components instanciation and mapping |
begin |
-- presynthesis checks |
CHKOVERSAMPLERP0 : if (CCSDS_RXTX_OVERSAMPLER_OVERSAMPLING_RATIO mod 2 /= 0) generate |
process |
begin |
report "ERROR: OVERSAMPLING RATIO HAS TO BE A MULTIPLE OF 2" severity failure; |
wait; |
end process; |
end generate CHKOVERSAMPLERP0; |
CHKOVERSAMPLERP1 : if (CCSDS_RXTX_OVERSAMPLER_OVERSAMPLING_RATIO = 0) generate |
process |
begin |
report "ERROR: OVERSAMPLING RATIO CANNOT BE 0" severity failure; |
wait; |
end process; |
end generate CHKOVERSAMPLERP1; |
-- internal processing |
--============================================================================= |
-- Begin of osrp |
-- Insert all 0 samples |
--============================================================================= |
-- read: rst_i, sam_i |
-- write: sam_o |
-- r/w: |
OSRP: process (clk_i) |
variable samples_counter: integer range 0 to CCSDS_RXTX_OVERSAMPLER_OVERSAMPLING_RATIO-1 := CCSDS_RXTX_OVERSAMPLER_OVERSAMPLING_RATIO-1; |
begin |
-- on each clock rising edge |
if rising_edge(clk_i) then |
-- reset signal received |
if (rst_i = '1') then |
sam_o <= (others => '0'); |
samples_counter := CCSDS_RXTX_OVERSAMPLER_OVERSAMPLING_RATIO-1; |
else |
if (sam_val_i = '1') then |
sam_val_o <= '1'; |
if (CCSDS_RXTX_OVERSAMPLER_SYMBOL_DEPHASING = true) then |
if (samples_counter <= 0) then |
sam_o <= (others => '0'); |
samples_counter := CCSDS_RXTX_OVERSAMPLER_OVERSAMPLING_RATIO-1; |
else |
if (samples_counter = CCSDS_RXTX_OVERSAMPLER_OVERSAMPLING_RATIO/2) then |
sam_o <= sam_i; |
else |
sam_o <= (others => '0'); |
end if; |
samples_counter := samples_counter - 1; |
end if; |
else |
if (samples_counter <= 0) then |
sam_o <= sam_i; |
samples_counter := CCSDS_RXTX_OVERSAMPLER_OVERSAMPLING_RATIO-1; |
else |
sam_o <= (others => '0'); |
samples_counter := samples_counter - 1; |
end if; |
end if; |
else |
sam_val_o <= '0'; |
end if; |
end if; |
end if; |
end process; |
end structure; |
/ccsds_rxtx_parameters.vhd
0,0 → 1,42
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_rxtx_parameters |
---- Version: 1.0.0 |
---- Description: |
---- Project / design specific parameters |
------------------------------- |
---- Author(s): |
---- Guillaume Rembert |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2015/11/17: initial release |
---- 2016/10/20: rework / remove non-systems parameters / each component has his own parameters set at proper level |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
package ccsds_rxtx_parameters is |
-- SYSTEM CONFIGURATION |
constant RXTX_SYSTEM_WB_DATA_BUS_SIZE: integer := 32;-- Wishbone slave data bus size (bits) |
constant RXTX_SYSTEM_WB_ADDR_BUS_SIZE: integer := 4;-- Wishbone slave address bus size (bits) |
-- RX CONFIGURATION |
constant RX_SYSTEM_AUTO_ENABLED: boolean := true;--Automatic activation of RX at startup |
-- TX CONFIGURATION |
constant TX_SYSTEM_AUTO_ENABLED: boolean := true;--Automatic activation of TX at startup |
constant TX_SYSTEM_AUTO_EXTERNAL: boolean := false;--Automatic configuration of TX to use external clock and data |
-- LAYERS CONFIGURATION |
-- APPLICATION LAYER |
-- PRESENTATION LAYER |
-- SESSION LAYER |
-- TRANSPORT LAYER |
-- NETWORK LAYER |
-- DATALINK LAYER |
-- PHYSICAL LAYER |
constant TX_PHYS_SIG_QUANT_DEPTH: integer := 8;-- DIGITAL PROCESSING QUANTIFICATION DEPTH IN BITS NUMBER |
constant RX_PHYS_SIG_QUANT_DEPTH: integer := 16;-- DIGITAL PROCESSING QUANTIFICATION DEPTH IN BITS NUMBER |
end ccsds_rxtx_parameters; |
/ccsds_rxtx_serdes.vhd
0,0 → 1,156
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_rxtx_serdes |
---- Version: 1.0.0 |
---- Description: |
---- Constant rate data serialiser/deserialiser |
---- Input: 1 clk / [SER2PAR: dat_ser_val_i <= '1' / dat_ser_i <= 'NEXTSERIALDATA' ] / [PAR2SER: dat_par_val_i <= '1' / dat_par_i <= "PARALLELDATA"] |
---- Timing requirements: SER2PAR: 1 clock cycle - PAR2SER: CCSDS_RXTX_SERDES_DEPTH clock cycles |
---- Output: [SER2PAR: dat_par_val_o <= "1" / dat_par_o <= "PARALLELIZEDDATA"] / [PAR2SER: dat_ser_val_o <= "1" / dat_ser_o <= "SERIALIZEDDATA"] |
---- Ressources requirements: CCSDS_RXTX_SERDES_DEPTH + 2*|log(CCSDS_RXTX_SERDES_DEPTH-1)/log(2)| + 2 registers |
------------------------------- |
---- Author(s): |
---- Guillaume Rembert |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2015/11/18: initial release |
---- 2016/10/27: review + add ser2par |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
library work; |
use work.ccsds_rxtx_parameters.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_rxtx_serdes / data serialiser/deserialiser |
--============================================================================= |
entity ccsds_rxtx_serdes is |
generic ( |
constant CCSDS_RXTX_SERDES_DEPTH : integer |
); |
port( |
-- inputs |
clk_i: in std_logic; -- parallel input data clock |
dat_par_i: in std_logic_vector(CCSDS_RXTX_SERDES_DEPTH-1 downto 0); -- parallel input data |
dat_par_val_i: in std_logic; -- parallel data valid indicator |
dat_ser_i: in std_logic; -- serial input data |
dat_ser_val_i: in std_logic; -- serial data valid indicator |
rst_i: in std_logic; -- system reset input |
-- outputs |
bus_o: out std_logic; -- par2ser busy indicator |
dat_par_o: out std_logic_vector(CCSDS_RXTX_SERDES_DEPTH-1 downto 0); -- parallel output data |
dat_par_val_o: out std_logic; -- parallel output data valid indicator |
dat_ser_o: out std_logic; -- serial output data |
dat_ser_val_o: out std_logic -- serial output data valid indicator |
); |
end ccsds_rxtx_serdes; |
|
--============================================================================= |
-- architecture declaration / internal processing |
--============================================================================= |
architecture rtl of ccsds_rxtx_serdes is |
|
-- internal variable signals |
signal wire_busy: std_logic := '0'; |
signal wire_data_par_valid: std_logic := '0'; |
signal wire_data_ser_valid: std_logic := '0'; |
signal serial_data_pointer: integer range 0 to CCSDS_RXTX_SERDES_DEPTH-1 := CCSDS_RXTX_SERDES_DEPTH-1; |
signal parallel_data_pointer: integer range 0 to CCSDS_RXTX_SERDES_DEPTH-1 := CCSDS_RXTX_SERDES_DEPTH-1; |
|
begin |
-- components instanciation and mapping |
bus_o <= wire_busy; |
dat_par_val_o <= wire_data_par_valid; |
dat_ser_val_o <= wire_data_ser_valid; |
-- presynthesis checks |
-- internal processing |
|
--============================================================================= |
-- Begin of par2serp |
-- Serialization of parallel data received starting with MSB |
--============================================================================= |
-- read: clk_i, rst_i, dat_par_i, dat_par_val_i |
-- write: dat_ser_o, wire_data_ser_valid, wire_busy |
-- r/w: parallel_data_pointer |
PAR2SERP : process (clk_i) |
variable serdes_memory: std_logic_vector(CCSDS_RXTX_SERDES_DEPTH-1 downto 0) := (others => '0'); |
begin |
-- on each clock rising edge |
if rising_edge(clk_i) then |
-- reset signal received |
if (rst_i = '1') then |
-- reset all |
wire_busy <= '0'; |
dat_ser_o <= '0'; |
wire_data_ser_valid <= '0'; |
parallel_data_pointer <= CCSDS_RXTX_SERDES_DEPTH-1; |
-- serdes_memory := (others => '0'); |
else |
if (dat_par_val_i = '1') and (parallel_data_pointer = CCSDS_RXTX_SERDES_DEPTH-1) then |
wire_busy <= '1'; |
serdes_memory := dat_par_i; |
-- serialise data on output_bus |
dat_ser_o <= dat_par_i(parallel_data_pointer); |
-- decrement position pointer |
parallel_data_pointer <= (parallel_data_pointer - 1) mod CCSDS_RXTX_SERDES_DEPTH; |
wire_data_ser_valid <= '1'; |
else |
if (parallel_data_pointer /= CCSDS_RXTX_SERDES_DEPTH-1) then |
wire_busy <= '1'; |
-- serialise data on output_bus |
dat_ser_o <= serdes_memory(parallel_data_pointer); |
-- decrement position pointer |
parallel_data_pointer <= (parallel_data_pointer - 1) mod CCSDS_RXTX_SERDES_DEPTH; |
wire_data_ser_valid <= '1'; |
else |
-- nothing to do |
wire_busy <= '0'; |
wire_data_ser_valid <= '0'; |
end if; |
end if; |
end if; |
end if; |
end process; |
--============================================================================= |
-- Begin of ser2parp |
-- Parallelization of serial data received |
--============================================================================= |
-- read: clk_i, rst_i, dat_ser_i, dat_ser_val_i |
-- write: dat_par_o, wire_data_par_valid |
-- r/w: serial_data_pointer |
SER2PARP : process (clk_i) |
begin |
-- on each clock rising edge |
if rising_edge(clk_i) then |
-- reset signal received |
if (rst_i = '1') then |
-- reset all |
dat_par_o <= (others => '0'); |
wire_data_par_valid <= '0'; |
serial_data_pointer <= CCSDS_RXTX_SERDES_DEPTH-1; |
else |
if (dat_ser_val_i = '1') then |
-- serialise data on output_bus |
dat_par_o(serial_data_pointer) <= dat_ser_i; |
if (serial_data_pointer = 0) then |
wire_data_par_valid <= '1'; |
else |
wire_data_par_valid <= '0'; |
end if; |
-- decrement position pointer |
serial_data_pointer <= (serial_data_pointer - 1) mod CCSDS_RXTX_SERDES_DEPTH; |
else |
wire_data_par_valid <= '0'; |
end if; |
end if; |
end if; |
end process; |
end rtl; |
--============================================================================= |
-- architecture end |
--============================================================================= |
/ccsds_rxtx_srrc.vhd
0,0 → 1,178
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_rxtx_srrc |
---- Version: 1.0.0 |
---- Description: |
---- Squared Raised Root Cosine FIR filter (pipelined systolic symetric architecture) |
---- Input: 1 clk / sam_val_i <= '1' / sam_i <= "SAMPLESDATATOBEFILTERED" |
---- Timing requirements: 1 clock cycle for valid output sample / delay = (6*CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO+1) / impulse response time = (6*CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO*2+1) |
---- Output: sam_val_o <= "1" / sam_o <= "FILTEREDSAMPLES" |
---- Ressources requirements: pipelined samples registers + fir coefficients registers + input adders registers + output adders registers + multipliers registers = ((FilterCoefficientsNumber - 1) * 2 + 1) * QuantizationDepth + FilterCoefficientsNumber * QuantizationDepth + FilterCoefficientsNumber * (QuantizationDepth + 1) + (2 * FilterCoefficientsNumber) * (QuantizationDepth * 2 + 1) registers |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/11/06: initial release |
------------------------------- |
-- Filter impulse response - SRRC(t): |
-- t = 0 => SRRC(0) = (1-B + 4*B/PI) |
-- t = +/-Ts/(4*B) => SRRC(+/-Ts/(4*B)) = (B/racine(2) * (1+2/PI) * sin(PI/(4*B)) + (1-2/PI) * cos(PI/(4*B))) |
-- t /= 0 and t /= Ts/(4*B) => SRRC(t) = (sin(PI.t.(1-B)/Ts) + 4.B.t.cos(PI.t.(1+B)/Ts)/Ts) / (PI.t.(1-((4.B.t)/Ts)^2)/Ts) |
-- t: time |
-- Ts: symbol period |
-- B: filter roll-off |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use ieee.math_real.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary rxtx srrc inputs and outputs |
--============================================================================= |
entity ccsds_rxtx_srrc is |
generic( |
constant CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE: integer range 0 to 2 := 1; -- 0=Dirichlet (Rectangular) / 1=Hamming / 2=Bartlett (Triangular) |
constant CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO: integer; |
constant CCSDS_RXTX_SRRC_ROLL_OFF: real := 0.5; |
constant CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH: integer |
); |
port( |
-- inputs |
clk_i: in std_logic; |
rst_i: in std_logic; |
sam_i: in std_logic_vector(CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH-1 downto 0); |
sam_val_i: in std_logic; |
-- outputs |
sam_o: out std_logic_vector(CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH-1 downto 0); |
sam_val_o: out std_logic |
); |
end ccsds_rxtx_srrc; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture rtl of ccsds_rxtx_srrc is |
-- internal constants |
constant CCSDS_RXTX_SRRC_RESPONSE_SYMBOL_CYCLES: integer:= 6; -- in symbol Time |
constant CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER: integer := CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO*CCSDS_RXTX_SRRC_RESPONSE_SYMBOL_CYCLES+1; |
constant CCSDS_RXTX_SRRC_SAMPLES_NUMBER: integer := (CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1)*2+1; |
constant CCSDS_RXTX_SRRC_SPECIFIC_COEFFICIENT_VALUE_T0: real := (1.0 - CCSDS_RXTX_SRRC_ROLL_OFF + 4.0 * CCSDS_RXTX_SRRC_ROLL_OFF / MATH_PI); |
constant CCSDS_RXTX_SRRC_SPECIFIC_COEFFICIENT_VALUE_TS: real := (CCSDS_RXTX_SRRC_ROLL_OFF / sqrt(2.0) * (1.0 + 2.0 / MATH_PI) * sin (MATH_PI / (4.0 * CCSDS_RXTX_SRRC_ROLL_OFF)) + (1.0 - 2.0 / MATH_PI) * cos (MATH_PI / (4.0 * CCSDS_RXTX_SRRC_ROLL_OFF))); |
constant CCSDS_RXTX_SRRC_NORMALIZATION_GAIN: real := (2.0**(CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH - 1) - 1.0) / CCSDS_RXTX_SRRC_SPECIFIC_COEFFICIENT_VALUE_T0; -- Exact value should be FIR coefficients RMS Gain / T0 Gain = Sqrt(Sum(Pow(coef,2)))) * Full Scale Value |
constant CCSDS_RXTX_SRRC_SIG_IN_ADD_SIZE: integer := CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH+1; |
constant CCSDS_RXTX_SRRC_SIG_MUL_SIZE: integer := CCSDS_RXTX_SRRC_SIG_IN_ADD_SIZE+CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH; |
constant CCSDS_RXTX_SRRC_SIG_OUT_ADD_SIZE: integer := CCSDS_RXTX_SRRC_SIG_MUL_SIZE; |
-- internal variable signals |
type samples_array is array(CCSDS_RXTX_SRRC_SAMPLES_NUMBER-1 downto 0) of signed(CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH-1 downto 0); |
type srrc_tap_array is array(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1 downto 0) of signed(CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH-1 downto 0); |
type srrc_multiplier_array is array(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1 downto 0) of signed(CCSDS_RXTX_SRRC_SIG_MUL_SIZE-1 downto 0); |
type srrc_input_adder_array is array(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1 downto 0) of signed(CCSDS_RXTX_SRRC_SIG_IN_ADD_SIZE-1 downto 0); |
type srrc_output_adder_array is array(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1 downto 0) of signed(CCSDS_RXTX_SRRC_SIG_OUT_ADD_SIZE-1 downto 0); |
signal sam_i_pipeline_registers: samples_array := (others => (others => '0')); |
signal srrc_coefficients: srrc_tap_array; |
signal srrc_multipliers_registers: srrc_multiplier_array := (others => (others => '0')); |
signal srrc_input_adders_registers: srrc_input_adder_array := (others => (others => '0')); |
signal srrc_output_adders_registers: srrc_output_adder_array := (others => (others => '0')); |
|
-- components instanciation and mapping |
begin |
-- SRRC coefficients generation |
-- At t = 0 |
srrc_coefficients(0) <= to_signed(integer(CCSDS_RXTX_SRRC_NORMALIZATION_GAIN * CCSDS_RXTX_SRRC_SPECIFIC_COEFFICIENT_VALUE_T0),CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH); |
-- Coefficients are symetrical / they are computed only for positive time response |
SRRC_COEFS_GENERATOR: for coefficient_counter in 1 to CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO*CCSDS_RXTX_SRRC_RESPONSE_SYMBOL_CYCLES generate |
-- At t = Ts/(4*B) |
SRRC_SPECIFIC_COEFS: if (real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO)/real(coefficient_counter) = 4.0*CCSDS_RXTX_SRRC_ROLL_OFF) generate |
SRRC_COEFS_WINDOW_DIRICHLET: if (CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE = 0) generate |
srrc_coefficients(coefficient_counter) <= to_signed(integer(CCSDS_RXTX_SRRC_NORMALIZATION_GAIN * CCSDS_RXTX_SRRC_SPECIFIC_COEFFICIENT_VALUE_TS),CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH); |
end generate SRRC_COEFS_WINDOW_DIRICHLET; |
SRRC_COEFS_WINDOW_HAMMING: if (CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE = 1) generate |
srrc_coefficients(coefficient_counter) <= to_signed(integer((0.53836 + 0.46164 * cos(2.0 * MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1))) * CCSDS_RXTX_SRRC_NORMALIZATION_GAIN * CCSDS_RXTX_SRRC_SPECIFIC_COEFFICIENT_VALUE_TS),CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH); |
end generate SRRC_COEFS_WINDOW_HAMMING; |
SRRC_COEFS_WINDOW_BARTLETT: if (CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE = 2) generate |
srrc_coefficients(0) <= to_signed(integer(CCSDS_RXTX_SRRC_NORMALIZATION_GAIN * CCSDS_RXTX_SRRC_SPECIFIC_COEFFICIENT_VALUE_T0),CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH); |
srrc_coefficients(coefficient_counter) <= to_signed(integer((1.0 - abs((real(coefficient_counter) - real(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1)/2.0) / real(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1)/2.0)) * CCSDS_RXTX_SRRC_NORMALIZATION_GAIN * CCSDS_RXTX_SRRC_SPECIFIC_COEFFICIENT_VALUE_TS),CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH); |
end generate SRRC_COEFS_WINDOW_BARTLETT; |
end generate SRRC_SPECIFIC_COEFS; |
-- At t > 0 and t /= Ts/(4*B) |
SRRC_GENERIC_COEFS: if (real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO)/real(coefficient_counter) /= 4.0*CCSDS_RXTX_SRRC_ROLL_OFF) generate |
SRRC_COEFS_WINDOW_DIRICHLET: if (CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE = 0) generate |
srrc_coefficients(coefficient_counter) <= to_signed(integer(CCSDS_RXTX_SRRC_NORMALIZATION_GAIN * (sin(MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 - CCSDS_RXTX_SRRC_ROLL_OFF)) + 4.0 * CCSDS_RXTX_SRRC_ROLL_OFF * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * cos(MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 + CCSDS_RXTX_SRRC_ROLL_OFF))) / (MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 - (4.0 * CCSDS_RXTX_SRRC_ROLL_OFF * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO))**2))),CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH); |
end generate SRRC_COEFS_WINDOW_DIRICHLET; |
SRRC_COEFS_WINDOW_HAMMING: if (CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE = 1) generate |
srrc_coefficients(coefficient_counter) <= to_signed(integer((0.53836 + 0.46164 * cos(2.0 * MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1))) * CCSDS_RXTX_SRRC_NORMALIZATION_GAIN * (sin(MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 - CCSDS_RXTX_SRRC_ROLL_OFF)) + 4.0 * CCSDS_RXTX_SRRC_ROLL_OFF * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * cos(MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 + CCSDS_RXTX_SRRC_ROLL_OFF))) / (MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 - (4.0 * CCSDS_RXTX_SRRC_ROLL_OFF * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO))**2))),CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH); |
end generate SRRC_COEFS_WINDOW_HAMMING; |
SRRC_COEFS_WINDOW_BARTLETT: if (CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE = 2) generate |
srrc_coefficients(coefficient_counter) <= to_signed(integer((1.0 - abs((real(coefficient_counter) - real(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1)/2.0) / real(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1)/2.0)) * CCSDS_RXTX_SRRC_NORMALIZATION_GAIN * (sin(MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 - CCSDS_RXTX_SRRC_ROLL_OFF)) + 4.0 * CCSDS_RXTX_SRRC_ROLL_OFF * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * cos(MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 + CCSDS_RXTX_SRRC_ROLL_OFF))) / (MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 - (4.0 * CCSDS_RXTX_SRRC_ROLL_OFF * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO))**2))),CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH); |
end generate SRRC_COEFS_WINDOW_BARTLETT; |
end generate SRRC_GENERIC_COEFS; |
end generate SRRC_COEFS_GENERATOR; |
-- presynthesis checks |
CHKSRRCP0: if CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO mod 2 /= 0 generate |
process |
begin |
report "ERROR: SRRC OVERSAMPLING RATIO MUST BE A MULTIPLE OF 2" severity failure; |
wait; |
end process; |
end generate CHKSRRCP0; |
CHKSRRCP1: if CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO = 0 generate |
process |
begin |
report "ERROR: SRRC OVERSAMPLING RATIO CANNOT BE NULL" severity failure; |
wait; |
end process; |
end generate CHKSRRCP1; |
CHKSRRCP2: if (CCSDS_RXTX_SRRC_ROLL_OFF < 0.0) or (CCSDS_RXTX_SRRC_ROLL_OFF > 1.0) generate |
process |
begin |
report "ERROR: SRRC ROLL OFF HAS TO BE BETWEEN 0.0 AND 1.0" severity failure; |
wait; |
end process; |
end generate CHKSRRCP2; |
-- internal processing |
--============================================================================= |
-- Begin of srrcp |
-- FIR filter coefficients |
--============================================================================= |
-- read: rst_i, sam_val_i, sam_i |
-- write: sam_o, sam_val_o |
-- r/w: sam_i_memory, sam_i_pipeline_registers, srrc_adders_registers, srrc_multipliers_registers |
SRRCP: process (clk_i) |
variable srrc_zero_in: signed(CCSDS_RXTX_SRRC_SIG_IN_ADD_SIZE-1 downto 0) := (others => '0'); |
variable srrc_zero_out: signed(CCSDS_RXTX_SRRC_SIG_OUT_ADD_SIZE-1 downto 0) := (others => '0'); |
begin |
-- on each clock rising edge |
if rising_edge(clk_i) then |
-- reset signal received |
if (rst_i = '1') then |
sam_o <= (others => '0'); |
sam_val_o <= '0'; |
else |
if (sam_val_i = '1') then |
sam_val_o <= '1'; |
sam_i_pipeline_registers(0) <= signed(sam_i); |
sam_i_pipeline_registers(CCSDS_RXTX_SRRC_SAMPLES_NUMBER-1 downto 1) <= sam_i_pipeline_registers(CCSDS_RXTX_SRRC_SAMPLES_NUMBER-2 downto 0); |
for i in 0 to CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1 loop |
srrc_multipliers_registers(i) <= srrc_input_adders_registers(i) * srrc_coefficients(i); |
if (i = 0) then |
srrc_input_adders_registers(i) <= sam_i_pipeline_registers(0) + srrc_zero_in; |
srrc_output_adders_registers(i) <= srrc_multipliers_registers(i) + srrc_zero_out; |
else |
srrc_input_adders_registers(i) <= sam_i_pipeline_registers(0) + srrc_zero_in + sam_i_pipeline_registers(i*2); |
srrc_output_adders_registers(i) <= srrc_multipliers_registers(i) + srrc_output_adders_registers(i-1); |
end if; |
end loop; |
sam_o <= std_logic_vector(srrc_output_adders_registers(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1)(CCSDS_RXTX_SRRC_SIG_OUT_ADD_SIZE-1 downto CCSDS_RXTX_SRRC_SIG_OUT_ADD_SIZE-CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH)); |
else |
sam_val_o <= '0'; |
end if; |
end if; |
end if; |
end process; |
end rtl; |
/ccsds_rxtx_top.vhd
0,0 → 1,322
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_rxtx_top |
---- Version: 1.0.0 |
---- Description: CCSDS compliant RX/TX for space communications |
---- TX Modulations: BPSK, QPSK, Offset-QPSK, QAM, Offset-QAM |
---- RX Performances: QAM: min Eb/N0 = XdB, max frequency shift = X Hz (Doppler + speed), max frequency shift rate = X Hz / secs (Doppler + acceleration), synchronisation, agc / dynamic range, filters capabilities, multipaths, ... |
---- This is the entry point / top level entity |
---- WB slave interface, RX/TX external inputs/outputs |
---- Synchronized with rising edge of clocks |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/02/26: initial release - only basic RX-TX capabilities through direct R/W on WB Bus / no dynamic configuration capabilities |
---- 2016/10/18: major rework / implementation of new architecture |
------------------------------- |
-- TODO: additionnal modulations: ASK, FSK, GMSK, OFDM, CDMA |
-- TODO: dynamic modulation and coding |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
library work; |
use work.ccsds_rxtx_parameters.all; |
use work.ccsds_rxtx_functions.all; |
--use work.ccsds_rxtx_constants.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_rxtx_top / overall rx-tx external physical inputs and outputs |
--============================================================================= |
entity ccsds_rxtx_top is |
generic ( |
CCSDS_RXTX_RX_AUTO_ENABLED: boolean := RX_SYSTEM_AUTO_ENABLED; |
CCSDS_RXTX_RX_PHYS_SIG_QUANT_DEPTH: integer := RX_PHYS_SIG_QUANT_DEPTH; |
CCSDS_RXTX_TX_AUTO_ENABLED: boolean := TX_SYSTEM_AUTO_ENABLED; |
CCSDS_RXTX_TX_AUTO_EXTERNAL: boolean := TX_SYSTEM_AUTO_EXTERNAL; |
CCSDS_RXTX_TX_PHYS_SIG_QUANT_DEPTH: integer := TX_PHYS_SIG_QUANT_DEPTH; |
CCSDS_RXTX_WB_ADDR_BUS_SIZE: integer := RXTX_SYSTEM_WB_ADDR_BUS_SIZE; |
CCSDS_RXTX_WB_DATA_BUS_SIZE: integer := RXTX_SYSTEM_WB_DATA_BUS_SIZE |
); |
port( |
-- system wide inputs |
--rst_i: in std_logic; -- implement external system reset port? |
-- system wide outputs |
-- wishbone slave bus connections / to the master CPU |
-- wb inputs |
wb_adr_i: in std_logic_vector(CCSDS_RXTX_WB_ADDR_BUS_SIZE-1 downto 0); -- address input array |
wb_clk_i: in std_logic; -- clock input / wb operations are always on rising edge of clk |
wb_cyc_i: in std_logic; -- cycle input / valid bus cycle in progress |
wb_dat_i: in std_logic_vector(CCSDS_RXTX_WB_DATA_BUS_SIZE-1 downto 0); -- data input array |
--wb_lock_i: out std_logic; -- lock input / current bus cycle is uninterruptible |
wb_rst_i: in std_logic; -- reset input |
--wb_sel_i: in std_logic_vector(3 downto 0); -- select input array / related to wb_dat_i + wb_dat_o / indicates where valid data is placed on the array / provide data granularity |
wb_stb_i: in std_logic; -- strobe input / slave is selected |
--wb_tga_i: in std_logic; -- address tag type / related to wb_adr_i / qualified by wb_stb_i / TBD |
--wb_tgc_i: in std_logic; -- cycle tag type / qualified by wb_cyc_i / TBD |
--wb_tgd_i: in std_logic; -- data tag type / related to wb_dat_i / ex: parity protection, ecc, timestamps |
wb_we_i: in std_logic; -- write enable input / indicates if cycle is of write or read type |
-- wb outputs |
wb_ack_o: out std_logic; -- acknowledge output / normal bus cycle termination |
wb_dat_o: out std_logic_vector(CCSDS_RXTX_WB_DATA_BUS_SIZE-1 downto 0); -- data output array |
wb_err_o: out std_logic; -- error output / abnormal bus cycle termination |
wb_rty_o: out std_logic; -- retry output / not ready - retry bus cycle |
--wb_tgd_o: out std_logic; -- data tag type / related to wb_dat_o / ex: parity protection, ecc, timestamps |
-- RX connections |
-- rx inputs |
rx_clk_i: in std_logic; -- received samples clock |
rx_sam_i_i: in std_logic_vector(CCSDS_RXTX_RX_PHYS_SIG_QUANT_DEPTH-1 downto 0); -- i samples |
rx_sam_q_i: in std_logic_vector(CCSDS_RXTX_RX_PHYS_SIG_QUANT_DEPTH-1 downto 0); -- q samples |
-- rx outputs |
rx_ena_o: out std_logic; -- rx enabled status indicator |
rx_irq_o: out std_logic; -- interrupt request output / data received indicator |
-- TX connections |
-- tx inputs |
tx_clk_i: in std_logic; -- output samples clock |
tx_dat_ser_i: in std_logic; -- direct data serial input |
-- tx outputs |
tx_buf_ful_o: out std_logic; -- buffer full / data overflow indicator |
tx_clk_o: out std_logic; -- emitted samples clock |
tx_ena_o: out std_logic; -- tx enabled status indicator |
tx_idl_o: out std_logic; -- idle status / data-padding indicator |
tx_sam_i_o: out std_logic_vector(CCSDS_RXTX_TX_PHYS_SIG_QUANT_DEPTH-1 downto 0); -- i samples |
tx_sam_q_o: out std_logic_vector(CCSDS_RXTX_TX_PHYS_SIG_QUANT_DEPTH-1 downto 0) -- q samples |
); |
end ccsds_rxtx_top; |
|
--============================================================================= |
-- architecture declaration / internal connections |
--============================================================================= |
architecture structure of ccsds_rxtx_top is |
-- components declaration |
component ccsds_rx is |
generic ( |
CCSDS_RX_PHYS_SIG_QUANT_DEPTH : integer; |
CCSDS_RX_DATA_BUS_SIZE: integer |
); |
port( |
rst_i: in std_logic; -- system reset |
ena_i: in std_logic; -- system enable |
clk_i: in std_logic; -- input samples clock |
sam_i_i: in std_logic_vector(CCSDS_RX_PHYS_SIG_QUANT_DEPTH-1 downto 0); -- in-phased parallel complex samples |
sam_q_i: in std_logic_vector(CCSDS_RX_PHYS_SIG_QUANT_DEPTH-1 downto 0); -- quadrature-phased parallel complex samples |
dat_nxt_i: in std_logic; -- next data |
irq_o: out std_logic; -- data ready to be read / IRQ signal |
dat_o: out std_logic_vector(CCSDS_RX_DATA_BUS_SIZE-1 downto 0); -- received data parallel output |
dat_val_o: out std_logic; -- data valid |
buf_dat_ful_o: out std_logic; -- data buffer status indicator |
buf_fra_ful_o: out std_logic; -- frames buffer status indicator |
buf_bit_ful_o: out std_logic; -- bits buffer status indicator |
ena_o: out std_logic -- enabled status indicator |
); |
end component; |
component ccsds_tx is |
generic ( |
CCSDS_TX_PHYS_SIG_QUANT_DEPTH : integer; |
CCSDS_TX_DATA_BUS_SIZE: integer |
); |
port( |
rst_i: in std_logic; |
ena_i: in std_logic; |
clk_i: in std_logic; |
in_sel_i: in std_logic; |
dat_val_i: in std_logic; |
dat_par_i: in std_logic_vector(CCSDS_TX_DATA_BUS_SIZE-1 downto 0); |
dat_ser_i: in std_logic; |
buf_ful_o: out std_logic; |
clk_o: out std_logic; |
idl_o: out std_logic; |
sam_i_o: out std_logic_vector(CCSDS_TX_PHYS_SIG_QUANT_DEPTH-1 downto 0); |
sam_q_o: out std_logic_vector(CCSDS_TX_PHYS_SIG_QUANT_DEPTH-1 downto 0); |
ena_o: out std_logic |
); |
end component; |
signal wire_rst: std_logic; |
signal wire_rx_ena: std_logic := convert_boolean_to_std_logic(CCSDS_RXTX_RX_AUTO_ENABLED); |
signal wire_rx_data_valid: std_logic; |
signal wire_rx_data_next: std_logic := '0'; |
signal wire_rx_buffer_data_full: std_logic; |
signal wire_rx_buffer_frames_full: std_logic; |
signal wire_rx_buffer_bits_full: std_logic; |
signal wire_tx_clk: std_logic; |
signal wire_tx_ena: std_logic := convert_boolean_to_std_logic(CCSDS_RXTX_TX_AUTO_ENABLED); |
signal wire_tx_ext: std_logic := convert_boolean_to_std_logic(CCSDS_RXTX_TX_AUTO_EXTERNAL); |
signal wire_tx_data_valid: std_logic := '0'; |
signal wire_tx_buf_ful: std_logic; |
signal wire_rx_data: std_logic_vector(CCSDS_RXTX_WB_DATA_BUS_SIZE-1 downto 0); |
signal wire_tx_data: std_logic_vector(CCSDS_RXTX_WB_DATA_BUS_SIZE-1 downto 0) := (others => '0'); |
|
--============================================================================= |
-- architecture begin |
--============================================================================= |
begin |
-- components entities instantiation |
rx_001: ccsds_rx |
generic map( |
CCSDS_RX_PHYS_SIG_QUANT_DEPTH => CCSDS_RXTX_RX_PHYS_SIG_QUANT_DEPTH, |
CCSDS_RX_DATA_BUS_SIZE => CCSDS_RXTX_WB_DATA_BUS_SIZE |
) |
port map( |
rst_i => wb_rst_i, |
ena_i => wire_rx_ena, |
clk_i => rx_clk_i, |
sam_i_i => rx_sam_i_i, |
sam_q_i => rx_sam_q_i, |
dat_nxt_i => wire_rx_data_next, |
irq_o => rx_irq_o, |
dat_o => wire_rx_data, |
dat_val_o => wire_rx_data_valid, |
buf_dat_ful_o => wire_rx_buffer_data_full, |
buf_fra_ful_o => wire_rx_buffer_frames_full, |
buf_bit_ful_o => wire_rx_buffer_bits_full, |
ena_o => rx_ena_o |
); |
tx_001: ccsds_tx |
generic map( |
CCSDS_TX_PHYS_SIG_QUANT_DEPTH => CCSDS_RXTX_TX_PHYS_SIG_QUANT_DEPTH, |
CCSDS_TX_DATA_BUS_SIZE => CCSDS_RXTX_WB_DATA_BUS_SIZE |
) |
port map( |
clk_i => tx_clk_i, |
rst_i => wb_rst_i, |
ena_i => wire_tx_ena, |
in_sel_i => wire_tx_ext, |
dat_val_i => wire_tx_data_valid, |
dat_par_i => wire_tx_data, |
dat_ser_i => tx_dat_ser_i, |
buf_ful_o => wire_tx_buf_ful, |
clk_o => tx_clk_o, |
idl_o => tx_idl_o, |
sam_i_o => tx_sam_i_o, |
sam_q_o => tx_sam_q_o, |
ena_o => tx_ena_o |
); |
tx_buf_ful_o <= wire_tx_buf_ful; |
--============================================================================= |
-- Begin of wbstartp |
-- In charge of wishbone bus interactions + rx/tx management through it |
--============================================================================= |
-- read: wb_clk_i, wb_rst_i, wb_cyc_i, wb_stb_i, wb_dat_i |
-- write: wb_ack_o, wb_err_o, wb_rty_o, (rx_/tx_XXX:rst_i), wb_dat_o, wire_rst, wire_irq, wire_rx_ena, wire_tx_ena |
-- r/w: wire_tx_ext |
WBSTARTP : process (wb_clk_i) |
variable ack_state: std_logic := '0'; |
-- variables instantiation |
begin |
-- on each wb clock rising edge |
if rising_edge(wb_clk_i) then |
-- wb reset signal received |
if (wb_rst_i = '1') then |
-- reinitialize all dyn elements to default value |
ack_state := '0'; |
wire_rx_ena <= convert_boolean_to_std_logic(CCSDS_RXTX_RX_AUTO_ENABLED); |
wire_tx_ena <= convert_boolean_to_std_logic(CCSDS_RXTX_TX_AUTO_ENABLED); |
-- reinitialize all outputs |
wire_tx_ext <= convert_boolean_to_std_logic(CCSDS_RXTX_TX_AUTO_EXTERNAL); |
if (CCSDS_RXTX_TX_AUTO_EXTERNAL = false) then |
wire_tx_data_valid <= '0'; |
else |
wire_tx_data_valid <= '1'; |
end if; |
wb_dat_o <= (others => '0'); |
wb_ack_o <= '0'; |
wb_err_o <= '0'; |
wb_rty_o <= '0'; |
else |
if (wb_cyc_i = '1') and (wb_stb_i = '1') then |
-- single classic standard read cycle |
if (wb_we_i = '0') then |
if (wb_adr_i = "0000") then |
-- classic rx cycle - forward data from rx to master |
if (ack_state = '0') then |
wb_dat_o <= wire_rx_data; |
wb_ack_o <= '0'; |
ack_state := '1'; |
else |
wb_dat_o <= (others => '0'); |
wb_ack_o <= '1'; |
ack_state := '0'; |
end if; |
else |
wb_err_o <= '1'; |
wb_rty_o <= '1'; |
end if; |
-- single write cycle |
else |
wb_dat_o <= (others => '0'); |
-- classic tx cycle - store and forward data from master to tx |
if (wb_adr_i = "0000") then |
-- check internal configuration |
if (wire_tx_ext = '0') then |
if (wire_tx_buf_ful = '0') and (ack_state = '0') then |
wb_ack_o <= '1'; |
ack_state := '1'; |
wire_tx_data <= wb_dat_i; |
wire_tx_data_valid <= '1'; |
else |
if (ack_state = '1') then |
wire_tx_data_valid <= '0'; |
wb_ack_o <= '0'; |
ack_state := '0'; |
else |
wb_ack_o <= '0'; |
wb_err_o <= '1'; |
wb_rty_o <= '1'; |
end if; |
end if; |
else |
wb_ack_o <= '0'; |
wb_err_o <= '1'; |
wb_rty_o <= '1'; |
end if; |
-- RX configuration cycle - set general rx parameters |
elsif (wb_adr_i = "0001") then |
if (ack_state = '0') then |
wire_rx_ena <= wb_dat_i(0); |
wb_ack_o <= '1'; |
ack_state := '1'; |
else |
wb_ack_o <= '0'; |
ack_state := '0'; |
end if; |
-- TX configuration cycle - set general tx parameters |
elsif (wb_adr_i = "0010") then |
if (ack_state = '0') then |
wire_tx_ena <= wb_dat_i(0); |
wire_tx_ext <= wb_dat_i(1); |
wb_ack_o <= '1'; |
ack_state := '1'; |
else |
wb_ack_o <= '0'; |
ack_state := '0'; |
end if; |
else |
wb_ack_o <= '0'; |
wb_err_o <= '1'; |
wb_rty_o <= '1'; |
end if; |
end if; |
else |
wb_dat_o <= (others => '0'); |
wb_ack_o <= '0'; |
wb_err_o <= '0'; |
wb_rty_o <= '0'; |
ack_state := '0'; |
if (wire_tx_ext = '0') then |
wire_tx_data_valid <= '0'; |
else |
wire_tx_data_valid <= '1'; |
end if; |
end if; |
end if; |
end if; |
end process; |
end structure; |
--============================================================================= |
-- architecture end |
--============================================================================= |
/ccsds_rxtx_types.vhd
0,0 → 1,25
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_rxtx_types |
---- Version: 1.0.0 |
---- Description: |
---- TO BE DONE |
------------------------------- |
---- Author(s): |
---- Guillaume Rembert |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2017/01/15: initial release |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
package ccsds_rxtx_types is |
type std_logic_vector_array is array (natural range <>, natural range <>) of std_logic; |
type boolean_array is array (natural range <>) of boolean; |
end ccsds_rxtx_types; |
/ccsds_tx.vhd
0,0 → 1,222
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_tx |
---- Version: 1.0.0 |
---- Description: |
---- CCSDS compliant TX |
------------------------------- |
---- Author(s): |
---- Guillaume Rembert |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2015/11/17: initial release |
---- 2016/10/19: rework |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary tx external physical inputs and outputs |
--============================================================================= |
entity ccsds_tx is |
generic ( |
constant CCSDS_TX_BITS_PER_SYMBOL: integer := 1; |
constant CCSDS_TX_BUFFER_SIZE: integer := 16; -- max number of words stored for burst write at full speed when datalinklayer is full |
constant CCSDS_TX_MODULATION_TYPE: integer := 1; -- 1=QAM/QPSK / 2=BPSK |
constant CCSDS_TX_DATA_BUS_SIZE: integer; |
constant CCSDS_TX_OVERSAMPLING_RATIO: integer := 4; -- symbols to samples over-sampling ratio |
constant CCSDS_TX_PHYS_SIG_QUANT_DEPTH : integer |
); |
port( |
-- inputs |
clk_i: in std_logic; -- transmitted samples clock |
dat_par_i: in std_logic_vector(CCSDS_TX_DATA_BUS_SIZE-1 downto 0); -- transmitted parallel data input |
dat_ser_i: in std_logic; -- transmitted serial data input |
dat_val_i: in std_logic; -- transmitted data valid input |
ena_i: in std_logic; -- system enable input |
in_sel_i: in std_logic; -- parallel / serial input selection |
rst_i: in std_logic; -- system reset input |
-- outputs |
buf_ful_o: out std_logic; -- buffer full indicator |
clk_o: out std_logic; -- output samples clock |
ena_o: out std_logic; -- enabled status indicator |
idl_o: out std_logic; -- idle data insertion indicator |
sam_i_o: out std_logic_vector(CCSDS_TX_PHYS_SIG_QUANT_DEPTH-1 downto 0); -- in-phased parallel complex samples |
sam_q_o: out std_logic_vector(CCSDS_TX_PHYS_SIG_QUANT_DEPTH-1 downto 0) -- quadrature-phased parallel complex samples |
); |
end ccsds_tx; |
|
--============================================================================= |
-- architecture declaration / internal connections |
--============================================================================= |
architecture structure of ccsds_tx is |
component ccsds_tx_manager is |
generic( |
CCSDS_TX_MANAGER_BITS_PER_SYMBOL: integer; |
CCSDS_TX_MANAGER_MODULATION_TYPE: integer; |
CCSDS_TX_MANAGER_DATA_BUS_SIZE : integer; |
CCSDS_TX_MANAGER_OVERSAMPLING_RATIO: integer |
); |
port( |
clk_i: in std_logic; |
clk_bit_o: out std_logic; |
clk_dat_o: out std_logic; |
clk_sam_o: out std_logic; |
clk_sym_o: out std_logic; |
rst_i: in std_logic; |
ena_i: in std_logic; |
ena_o: out std_logic; |
in_sel_i: in std_logic; |
dat_par_i: in std_logic_vector(CCSDS_TX_MANAGER_DATA_BUS_SIZE-1 downto 0); |
dat_ser_i: in std_logic; |
dat_val_i: in std_logic; |
dat_val_o: out std_logic; |
dat_o: out std_logic_vector(CCSDS_TX_MANAGER_DATA_BUS_SIZE-1 downto 0) |
); |
end component; |
component ccsds_rxtx_buffer is |
generic( |
constant CCSDS_RXTX_BUFFER_DATA_BUS_SIZE : integer; |
constant CCSDS_RXTX_BUFFER_SIZE : integer |
); |
port( |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_RXTX_BUFFER_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
dat_nxt_i: in std_logic; |
rst_i: in std_logic; |
buf_emp_o: out std_logic; |
buf_ful_o: out std_logic; |
dat_o: out std_logic_vector(CCSDS_RXTX_BUFFER_DATA_BUS_SIZE-1 downto 0); |
dat_val_o: out std_logic |
); |
end component; |
component ccsds_tx_datalink_layer is |
generic( |
CCSDS_TX_DATALINK_DATA_BUS_SIZE: integer; |
CCSDS_TX_DATALINK_CODER_DIFFERENTIAL_BITS_PER_CODEWORD: integer |
); |
port( |
clk_bit_i: in std_logic; |
clk_dat_i: in std_logic; |
rst_i: in std_logic; |
dat_val_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_DATALINK_DATA_BUS_SIZE-1 downto 0); |
dat_val_o: out std_logic; |
dat_o: out std_logic_vector(CCSDS_TX_DATALINK_DATA_BUS_SIZE-1 downto 0); |
dat_nxt_o: out std_logic; |
idl_o: out std_logic |
); |
end component; |
component ccsds_tx_physical_layer is |
generic( |
CCSDS_TX_PHYSICAL_BITS_PER_SYMBOL: integer; |
CCSDS_TX_PHYSICAL_MODULATION_TYPE: integer; |
CCSDS_TX_PHYSICAL_DATA_BUS_SIZE: integer; |
CCSDS_TX_PHYSICAL_OVERSAMPLING_RATIO: integer; |
CCSDS_TX_PHYSICAL_SIG_QUANT_DEPTH: integer |
); |
port( |
clk_sam_i: in std_logic; |
clk_sym_i: in std_logic; |
rst_i: in std_logic; |
sam_i_o: out std_logic_vector(CCSDS_TX_PHYSICAL_SIG_QUANT_DEPTH-1 downto 0); |
sam_q_o: out std_logic_vector(CCSDS_TX_PHYSICAL_SIG_QUANT_DEPTH-1 downto 0); |
dat_i: in std_logic_vector(CCSDS_TX_PHYSICAL_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic |
); |
end component; |
|
signal wire_dat_nxt_buf: std_logic; |
signal wire_dat_val_buf: std_logic; |
signal wire_dat_val_dat: std_logic; |
signal wire_dat_val_man: std_logic; |
signal wire_dat_buf: std_logic_vector(CCSDS_TX_DATA_BUS_SIZE-1 downto 0); |
signal wire_dat_dat: std_logic_vector(CCSDS_TX_DATA_BUS_SIZE-1 downto 0); |
signal wire_dat_man: std_logic_vector(CCSDS_TX_DATA_BUS_SIZE-1 downto 0); |
signal wire_clk_dat: std_logic; |
signal wire_clk_sam: std_logic; |
signal wire_clk_sym: std_logic; |
signal wire_clk_bit: std_logic; |
signal wire_rst_man: std_logic; |
|
begin |
tx_manager_0: ccsds_tx_manager |
generic map( |
CCSDS_TX_MANAGER_BITS_PER_SYMBOL => CCSDS_TX_BITS_PER_SYMBOL, |
CCSDS_TX_MANAGER_MODULATION_TYPE => CCSDS_TX_MODULATION_TYPE, |
CCSDS_TX_MANAGER_DATA_BUS_SIZE => CCSDS_TX_DATA_BUS_SIZE, |
CCSDS_TX_MANAGER_OVERSAMPLING_RATIO => CCSDS_TX_OVERSAMPLING_RATIO |
) |
port map( |
clk_i => clk_i, |
clk_bit_o => wire_clk_bit, |
clk_dat_o => wire_clk_dat, |
clk_sam_o => wire_clk_sam, |
clk_sym_o => wire_clk_sym, |
rst_i => rst_i, |
ena_i => ena_i, |
ena_o => ena_o, |
in_sel_i => in_sel_i, |
dat_val_i => dat_val_i, |
dat_par_i => dat_par_i, |
dat_ser_i => dat_ser_i, |
dat_val_o => wire_dat_val_man, |
dat_o => wire_dat_man |
); |
tx_buffer_0: ccsds_rxtx_buffer |
generic map( |
CCSDS_RXTX_BUFFER_DATA_BUS_SIZE => CCSDS_TX_DATA_BUS_SIZE, |
CCSDS_RXTX_BUFFER_SIZE => CCSDS_TX_BUFFER_SIZE |
) |
port map( |
clk_i => wire_clk_dat, |
rst_i => rst_i, |
dat_nxt_i => wire_dat_nxt_buf, |
dat_val_i => wire_dat_val_man, |
dat_i => wire_dat_man, |
dat_val_o => wire_dat_val_buf, |
-- buf_emp_o => , |
buf_ful_o => buf_ful_o, |
dat_o => wire_dat_buf |
); |
tx_datalink_layer_0: ccsds_tx_datalink_layer |
generic map( |
CCSDS_TX_DATALINK_DATA_BUS_SIZE => CCSDS_TX_DATA_BUS_SIZE, |
CCSDS_TX_DATALINK_CODER_DIFFERENTIAL_BITS_PER_CODEWORD => CCSDS_TX_BITS_PER_SYMBOL |
) |
port map( |
clk_dat_i => wire_clk_dat, |
clk_bit_i => wire_clk_bit, |
rst_i => rst_i, |
dat_val_i => wire_dat_val_buf, |
dat_i => wire_dat_buf, |
dat_val_o => wire_dat_val_dat, |
dat_nxt_o => wire_dat_nxt_buf, |
dat_o => wire_dat_dat, |
idl_o => idl_o |
); |
tx_physical_layer_0: ccsds_tx_physical_layer |
generic map( |
CCSDS_TX_PHYSICAL_SIG_QUANT_DEPTH => CCSDS_TX_PHYS_SIG_QUANT_DEPTH, |
CCSDS_TX_PHYSICAL_DATA_BUS_SIZE => CCSDS_TX_DATA_BUS_SIZE, |
CCSDS_TX_PHYSICAL_MODULATION_TYPE => CCSDS_TX_MODULATION_TYPE, |
CCSDS_TX_PHYSICAL_BITS_PER_SYMBOL => CCSDS_TX_BITS_PER_SYMBOL, |
CCSDS_TX_PHYSICAL_OVERSAMPLING_RATIO => CCSDS_TX_OVERSAMPLING_RATIO |
) |
port map( |
clk_sym_i => wire_clk_sym, |
clk_sam_i => wire_clk_sam, |
rst_i => rst_i, |
sam_i_o => sam_i_o, |
sam_q_o => sam_q_o, |
dat_i => wire_dat_dat, |
dat_val_i => wire_dat_val_dat |
); |
clk_o <= wire_clk_sam; |
end structure; |
/ccsds_tx_coder.vhd
0,0 → 1,156
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_tx_coder |
---- Version: 1.0.0 |
---- Description: |
---- Implementation of standard CCSDS 131.0-B-2 |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/11/05: initial release |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary tx coder inputs and outputs |
--============================================================================= |
entity ccsds_tx_coder is |
generic( |
constant CCSDS_TX_CODER_ASM_LENGTH: integer; -- Attached Synchronization Marker length / in Bytes |
constant CCSDS_TX_CODER_DATA_BUS_SIZE: integer; -- in bits |
constant CCSDS_TX_CODER_DIFFERENTIAL_BITS_PER_CODEWORD: integer; -- Number of bits per codeword (should be equal to bits per symbol of lower link) |
constant CCSDS_TX_CODER_DIFFERENTIAL_ENABLED: boolean -- Enable differential coder |
); |
port( |
-- inputs |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_CODER_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
-- outputs |
dat_o: out std_logic_vector(CCSDS_TX_CODER_DATA_BUS_SIZE+CCSDS_TX_CODER_ASM_LENGTH*8-1 downto 0); |
dat_val_o: out std_logic |
); |
end ccsds_tx_coder; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture structure of ccsds_tx_coder is |
component ccsds_tx_coder_differential is |
generic( |
CCSDS_TX_CODER_DIFF_BITS_PER_CODEWORD: integer; |
CCSDS_TX_CODER_DIFF_DATA_BUS_SIZE: integer |
); |
port( |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_CODER_DIFF_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
dat_o: out std_logic_vector(CCSDS_TX_CODER_DIFF_DATA_BUS_SIZE-1 downto 0); |
dat_val_o: out std_logic |
); |
end component; |
component ccsds_tx_randomizer is |
generic( |
CCSDS_TX_RANDOMIZER_DATA_BUS_SIZE: integer |
); |
port( |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_RANDOMIZER_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
dat_o: out std_logic_vector(CCSDS_TX_RANDOMIZER_DATA_BUS_SIZE-1 downto 0); |
dat_val_o: out std_logic |
); |
end component; |
component ccsds_tx_synchronizer is |
generic( |
CCSDS_TX_ASM_LENGTH: integer; |
CCSDS_TX_ASM_DATA_BUS_SIZE: integer |
); |
port( |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_ASM_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
dat_o: out std_logic_vector(CCSDS_TX_ASM_DATA_BUS_SIZE+CCSDS_TX_ASM_LENGTH*8-1 downto 0); |
dat_val_o: out std_logic |
); |
end component; |
-- internal constants |
-- internal variable signals |
signal wire_coder_diff_dat_o: std_logic_vector(CCSDS_TX_CODER_DATA_BUS_SIZE+CCSDS_TX_CODER_ASM_LENGTH*8-1 downto 0); |
signal wire_coder_diff_dat_val_o: std_logic; |
signal wire_randomizer_dat_o: std_logic_vector(CCSDS_TX_CODER_DATA_BUS_SIZE-1 downto 0); |
signal wire_randomizer_dat_val_o: std_logic; |
signal wire_synchronizer_dat_o: std_logic_vector(CCSDS_TX_CODER_DATA_BUS_SIZE+CCSDS_TX_CODER_ASM_LENGTH*8-1 downto 0); |
signal wire_synchronizer_dat_val_o: std_logic; |
-- components instanciation and mapping |
begin |
tx_coder_randomizer_0: ccsds_tx_randomizer |
generic map( |
CCSDS_TX_RANDOMIZER_DATA_BUS_SIZE => CCSDS_TX_CODER_DATA_BUS_SIZE |
) |
port map( |
clk_i => clk_i, |
rst_i => rst_i, |
dat_val_i => dat_val_i, |
dat_i => dat_i, |
dat_val_o => wire_randomizer_dat_val_o, |
dat_o => wire_randomizer_dat_o |
); |
NODIFFCODERGENP: if (CCSDS_TX_CODER_DIFFERENTIAL_ENABLED = false) generate |
tx_coder_synchronizer_0: ccsds_tx_synchronizer |
generic map( |
CCSDS_TX_ASM_LENGTH => CCSDS_TX_CODER_ASM_LENGTH, |
CCSDS_TX_ASM_DATA_BUS_SIZE => CCSDS_TX_CODER_DATA_BUS_SIZE |
) |
port map( |
clk_i => clk_i, |
rst_i => rst_i, |
dat_val_i => wire_randomizer_dat_val_o, |
dat_i => wire_randomizer_dat_o, |
dat_val_o => dat_val_o, |
dat_o => dat_o |
); |
end generate NODIFFCODERGENP; |
DIFFCODERGENP: if (CCSDS_TX_CODER_DIFFERENTIAL_ENABLED = true) generate |
tx_coder_synchronizer_0: ccsds_tx_synchronizer |
generic map( |
CCSDS_TX_ASM_LENGTH => CCSDS_TX_CODER_ASM_LENGTH, |
CCSDS_TX_ASM_DATA_BUS_SIZE => CCSDS_TX_CODER_DATA_BUS_SIZE |
) |
port map( |
clk_i => clk_i, |
rst_i => rst_i, |
dat_val_i => wire_randomizer_dat_val_o, |
dat_i => wire_randomizer_dat_o, |
dat_val_o => wire_synchronizer_dat_val_o, |
dat_o => wire_synchronizer_dat_o |
); |
tx_coder_differential_0: ccsds_tx_coder_differential |
generic map( |
CCSDS_TX_CODER_DIFF_BITS_PER_CODEWORD => CCSDS_TX_CODER_DIFFERENTIAL_BITS_PER_CODEWORD, |
CCSDS_TX_CODER_DIFF_DATA_BUS_SIZE => CCSDS_TX_CODER_DATA_BUS_SIZE+CCSDS_TX_CODER_ASM_LENGTH*8 |
) |
port map( |
clk_i => clk_i, |
rst_i => rst_i, |
dat_val_i => wire_synchronizer_dat_val_o, |
dat_i => wire_synchronizer_dat_o, |
dat_val_o => dat_val_o, |
dat_o => dat_o |
); |
end generate DIFFCODERGENP; |
-- presynthesis checks |
-- internal processing |
end structure; |
/ccsds_tx_coder_convolutional.vhd
0,0 → 1,166
---- Design Name: ccsds_tx_coder_convolutional |
---- Version: 1.0.0 |
---- Description: |
---- Convolutional coder |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2017/01/15: initial release |
------------------------------- |
-- TODO: puncturation + input rate /= 1 |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
use work.ccsds_rxtx_functions.all; |
use work.ccsds_rxtx_types.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary tx convolutional coder inputs and outputs |
--============================================================================= |
entity ccsds_tx_coder_convolutional is |
generic( |
constant CCSDS_TX_CODER_CONV_CONNEXION_VECTORS: std_logic_vector_array := ("1111001", "1011011"); |
constant CCSDS_TX_CODER_CONV_CONSTRAINT_SIZE: integer := 7; -- in bits |
constant CCSDS_TX_CODER_CONV_DATA_BUS_SIZE: integer; -- in bits |
constant CCSDS_TX_CODER_CONV_OPERATING_MODE: integer := 1; -- 0=streaming / 1=truncated (reset state when new frame) //TODO: terminated trellis + tailbiting |
constant CCSDS_TX_CODER_CONV_OUTPUT_INVERSION: boolean_array := (false, true); |
constant CCSDS_TX_CODER_CONV_RATE_OUTPUT: integer := 2; -- in bits/operation |
constant CCSDS_TX_CODER_CONV_SEED: std_logic_vector := "000000" |
); |
port( |
-- inputs |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_CODER_CONV_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
-- outputs |
bus_o: out std_logic; |
dat_o: out std_logic_vector(CCSDS_TX_CODER_CONV_DATA_BUS_SIZE*CCSDS_TX_CODER_CONV_RATE_OUTPUT-1 downto 0); |
dat_val_o: out std_logic |
); |
end ccsds_tx_coder_convolutional; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture rtl of ccsds_tx_coder_convolutional is |
-- internal constants |
type connexion_vectors_array is array(CCSDS_TX_CODER_CONV_RATE_OUTPUT-1 downto 0) of std_logic_vector(CCSDS_TX_CODER_CONV_CONSTRAINT_SIZE-1 downto 0); |
signal connexion_vectors: connexion_vectors_array; |
constant connexion_vectors_array_size: integer := CCSDS_TX_CODER_CONV_CONNEXION_VECTORS'length; |
constant output_inversion_array_size: integer := CCSDS_TX_CODER_CONV_OUTPUT_INVERSION'length; |
-- internal variable signals |
signal coder_busy: std_logic := '0'; |
signal coder_memory: std_logic_vector(CCSDS_TX_CODER_CONV_CONSTRAINT_SIZE-2 downto 0) := CCSDS_TX_CODER_CONV_SEED; |
-- components instanciation and mapping |
begin |
bus_o <= coder_busy; |
CONNEXION_VECTORS_GENERATOR: for vector_counter in 0 to CCSDS_TX_CODER_CONV_RATE_OUTPUT-1 generate |
connexion_vectors(CCSDS_TX_CODER_CONV_RATE_OUTPUT-1-vector_counter) <= convert_std_logic_vector_array_to_std_logic_vector(CCSDS_TX_CODER_CONV_CONNEXION_VECTORS, vector_counter); |
end generate CONNEXION_VECTORS_GENERATOR; |
|
-- presynthesis checks |
CHKCODERP0 : if (CCSDS_TX_CODER_CONV_SEED'length /= CCSDS_TX_CODER_CONV_CONSTRAINT_SIZE-1) generate |
process |
begin |
report "ERROR: SEED SIZE HAS TO BE EQUAL TO CONSTRAINT SIZE - 1" severity failure; |
wait; |
end process; |
end generate CHKCODERP0; |
CHKCODERP1 : if (connexion_vectors_array_size /= CCSDS_TX_CODER_CONV_RATE_OUTPUT) generate |
process |
begin |
report "ERROR: CONNEXION VECTORS ARRAY SIZE HAS TO BE EQUAL TO OUTPUT RATE : " & integer'image(connexion_vectors_array_size) severity failure; |
wait; |
end process; |
end generate CHKCODERP1; |
CHKCODERP2 : if (output_inversion_array_size /= CCSDS_TX_CODER_CONV_RATE_OUTPUT) generate |
process |
begin |
report "ERROR: OUTPUT INVERSION ARRAY HAS TO BE EQUAL TO OUTPUT RATE" severity failure; |
wait; |
end process; |
end generate CHKCODERP2; |
|
-- internal processing |
--============================================================================= |
-- Begin of coderp |
-- Convolutional encode bits based on connexion vectors |
--============================================================================= |
-- read: rst_i, dat_i, dat_val_i |
-- write: dat_o, dat_val_o, coder_busy |
-- r/w: |
CODERP: process (clk_i) |
variable coder_data_pointer: integer range -1 to (CCSDS_TX_CODER_CONV_DATA_BUS_SIZE-1) := -1; |
variable coder_data: std_logic_vector(CCSDS_TX_CODER_CONV_DATA_BUS_SIZE-1 downto 0) := (others => '0'); |
variable coder_atomic_result: std_logic := '0'; |
begin |
-- on each clock rising edge |
if rising_edge(clk_i) then |
-- reset signal received |
if (rst_i = '1') then |
-- dat_o <= (others => '0'); |
dat_val_o <= '0'; |
coder_memory <= CCSDS_TX_CODER_CONV_SEED; |
coder_data_pointer := -1; |
coder_atomic_result := '0'; |
coder_busy <= '0'; |
else |
case coder_data_pointer is |
-- no current computation |
when -1 => |
dat_val_o <= '0'; |
-- reset on new frame behaviour |
if (CCSDS_TX_CODER_CONV_OPERATING_MODE = 1) then |
coder_memory <= CCSDS_TX_CODER_CONV_SEED; |
end if; |
-- store data |
if (dat_val_i = '1') then |
coder_data := dat_i; |
coder_busy <= '1'; |
coder_data_pointer := CCSDS_TX_CODER_CONV_DATA_BUS_SIZE-1; |
else |
-- nothing to be done |
coder_busy <= '0'; |
end if; |
-- processing |
when others => |
coder_busy <= '1'; |
dat_val_o <= '0'; |
-- shift memory |
coder_memory <= coder_memory(CCSDS_TX_CODER_CONV_CONSTRAINT_SIZE-3 downto 0) & coder_data(coder_data_pointer); |
-- compute output |
for i in CCSDS_TX_CODER_CONV_RATE_OUTPUT-1 downto 0 loop |
if (connexion_vectors(i)(CCSDS_TX_CODER_CONV_CONSTRAINT_SIZE-1) = '1') then |
coder_atomic_result := coder_data(coder_data_pointer); |
else |
coder_atomic_result := '0'; |
end if; |
for j in CCSDS_TX_CODER_CONV_CONSTRAINT_SIZE-2 downto 0 loop |
if (connexion_vectors(i)(j) = '1') then |
coder_atomic_result := coder_atomic_result xor coder_memory(CCSDS_TX_CODER_CONV_CONSTRAINT_SIZE-2-j); |
end if; |
end loop; |
if (CCSDS_TX_CODER_CONV_OUTPUT_INVERSION(CCSDS_TX_CODER_CONV_RATE_OUTPUT-1-i) = true) then |
dat_o(coder_data_pointer*CCSDS_TX_CODER_CONV_RATE_OUTPUT+i) <= not(coder_atomic_result); |
else |
dat_o(coder_data_pointer*CCSDS_TX_CODER_CONV_RATE_OUTPUT+i) <= coder_atomic_result; |
end if; |
end loop; |
-- output is computed |
if (coder_data_pointer = 0) then |
coder_busy <= '0'; |
dat_val_o <= '1'; |
end if; |
coder_data_pointer := coder_data_pointer - 1; |
end case; |
end if; |
end if; |
end process; |
end rtl; |
/ccsds_tx_coder_differential.vhd
0,0 → 1,89
---- Design Name: ccsds_tx_coder_differential |
---- Version: 1.0.0 |
---- Description: |
---- Word by word differential coder |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/11/18: initial release |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary tx differential coder inputs and outputs |
--============================================================================= |
entity ccsds_tx_coder_differential is |
generic( |
constant CCSDS_TX_CODER_DIFF_BITS_PER_CODEWORD: integer; |
constant CCSDS_TX_CODER_DIFF_DATA_BUS_SIZE: integer -- in bits |
); |
port( |
-- inputs |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_CODER_DIFF_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
-- outputs |
dat_o: out std_logic_vector(CCSDS_TX_CODER_DIFF_DATA_BUS_SIZE-1 downto 0); |
dat_val_o: out std_logic |
); |
end ccsds_tx_coder_differential; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture rtl of ccsds_tx_coder_differential is |
-- internal constants |
-- internal variable signals |
-- components instanciation and mapping |
begin |
-- presynthesis checks |
CHKCODERP0 : if (CCSDS_TX_CODER_DIFF_DATA_BUS_SIZE mod (CCSDS_TX_CODER_DIFF_BITS_PER_CODEWORD) /= 0) generate |
process |
begin |
report "ERROR: DATA BUS SIZE HAS TO BE A MULTIPLE OF BITS PER CODE WORD" severity failure; |
wait; |
end process; |
end generate CHKCODERP0; |
|
-- internal processing |
--============================================================================= |
-- Begin of coderdiffp |
-- Differential encode words |
--============================================================================= |
-- read: rst_i, dat_i, dat_val_i |
-- write: dat_o, dat_val_o |
-- r/w: |
CODERDIFFP: process (clk_i) |
variable prev_sym: std_logic_vector(CCSDS_TX_CODER_DIFF_BITS_PER_CODEWORD-1 downto 0) := (others => '0'); |
begin |
-- on each clock rising edge |
if rising_edge(clk_i) then |
-- reset signal received |
if (rst_i = '1') then |
dat_o <= (others => '0'); |
dat_val_o <= '0'; |
prev_sym := (others => '0'); |
else |
if (dat_val_i = '1') then |
dat_val_o <= '1'; |
dat_o(CCSDS_TX_CODER_DIFF_DATA_BUS_SIZE-1 downto CCSDS_TX_CODER_DIFF_DATA_BUS_SIZE-CCSDS_TX_CODER_DIFF_BITS_PER_CODEWORD) <= prev_sym xor dat_i(CCSDS_TX_CODER_DIFF_DATA_BUS_SIZE-1 downto CCSDS_TX_CODER_DIFF_DATA_BUS_SIZE-CCSDS_TX_CODER_DIFF_BITS_PER_CODEWORD); |
for i in CCSDS_TX_CODER_DIFF_DATA_BUS_SIZE/(CCSDS_TX_CODER_DIFF_BITS_PER_CODEWORD)-1 downto 1 loop |
dat_o(i*CCSDS_TX_CODER_DIFF_BITS_PER_CODEWORD-1 downto (i-1)*CCSDS_TX_CODER_DIFF_BITS_PER_CODEWORD) <= dat_i(i*CCSDS_TX_CODER_DIFF_BITS_PER_CODEWORD-1 downto (i-1)*CCSDS_TX_CODER_DIFF_BITS_PER_CODEWORD) xor dat_i((i+1)*CCSDS_TX_CODER_DIFF_BITS_PER_CODEWORD-1 downto i*CCSDS_TX_CODER_DIFF_BITS_PER_CODEWORD); |
end loop; |
prev_sym := dat_i(CCSDS_TX_CODER_DIFF_BITS_PER_CODEWORD-1 downto 0); |
else |
dat_val_o <= '0'; |
end if; |
end if; |
end if; |
end process; |
end rtl; |
/ccsds_tx_datalink_layer.vhd
0,0 → 1,192
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_tx_datalink_layer |
---- Version: 1.0.0 |
---- Description: |
---- TM (TeleMetry) Space Data Link Protocol |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2015/11/17: initial release |
---- 2016/10/21: rework based on TX final architecture |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary tx datalink layer inputs and outputs |
--============================================================================= |
entity ccsds_tx_datalink_layer is |
generic ( |
constant CCSDS_TX_DATALINK_ASM_LENGTH: integer := 4; -- Attached Synchronization Marker length / in Bytes |
constant CCSDS_TX_DATALINK_CODER_DIFFERENTIAL_ENABLED: boolean := false; -- Enable differential coder |
constant CCSDS_TX_DATALINK_CODER_DIFFERENTIAL_BITS_PER_CODEWORD: integer; -- Number of bits per codeword from differential coder |
constant CCSDS_TX_DATALINK_DATA_BUS_SIZE: integer; -- in bits |
constant CCSDS_TX_DATALINK_DATA_LENGTH: integer := 12; -- datagram data size (Bytes) / (has to be a multiple of CCSDS_TX_DATALINK_DATA_BUS_SIZE) |
constant CCSDS_TX_DATALINK_FOOTER_LENGTH: integer := 2; -- datagram footer length (Bytes) |
constant CCSDS_TX_DATALINK_HEADER_LENGTH: integer := 6 -- datagram header length (Bytes) |
); |
port( |
-- inputs |
clk_bit_i: in std_logic; |
clk_dat_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_DATALINK_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
-- outputs |
dat_o: out std_logic_vector(CCSDS_TX_DATALINK_DATA_BUS_SIZE-1 downto 0); |
dat_nxt_o: out std_logic; |
dat_val_o: out std_logic; |
idl_o: out std_logic |
); |
end ccsds_tx_datalink_layer; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture structure of ccsds_tx_datalink_layer is |
component ccsds_tx_framer is |
generic( |
CCSDS_TX_FRAMER_DATA_BUS_SIZE : integer; |
CCSDS_TX_FRAMER_DATA_LENGTH : integer; |
CCSDS_TX_FRAMER_FOOTER_LENGTH : integer; |
CCSDS_TX_FRAMER_HEADER_LENGTH : integer |
); |
port( |
clk_i: in std_logic; |
rst_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_FRAMER_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
dat_o: out std_logic_vector((CCSDS_TX_FRAMER_DATA_LENGTH+CCSDS_TX_FRAMER_HEADER_LENGTH+CCSDS_TX_FRAMER_FOOTER_LENGTH)*8-1 downto 0); |
dat_val_o: out std_logic; |
dat_nxt_o: out std_logic; |
idl_o: out std_logic |
); |
end component; |
component ccsds_tx_coder is |
generic( |
CCSDS_TX_CODER_DIFFERENTIAL_BITS_PER_CODEWORD: integer; |
CCSDS_TX_CODER_DIFFERENTIAL_ENABLED: boolean; |
CCSDS_TX_CODER_DATA_BUS_SIZE : integer; |
CCSDS_TX_CODER_ASM_LENGTH: integer |
); |
port( |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_CODER_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
dat_o: out std_logic_vector(CCSDS_TX_CODER_DATA_BUS_SIZE+CCSDS_TX_CODER_ASM_LENGTH*8-1 downto 0); |
dat_val_o: out std_logic |
); |
end component; |
|
-- internal constants |
constant FRAME_OUTPUT_SIZE: integer := (CCSDS_TX_DATALINK_DATA_LENGTH+CCSDS_TX_DATALINK_HEADER_LENGTH+CCSDS_TX_DATALINK_FOOTER_LENGTH+CCSDS_TX_DATALINK_ASM_LENGTH)*8; |
constant FRAME_OUTPUT_WORDS: integer := FRAME_OUTPUT_SIZE/CCSDS_TX_DATALINK_DATA_BUS_SIZE; |
|
-- interconnection signals |
signal wire_framer_data: std_logic_vector((CCSDS_TX_DATALINK_DATA_LENGTH+CCSDS_TX_DATALINK_HEADER_LENGTH+CCSDS_TX_DATALINK_FOOTER_LENGTH)*8-1 downto 0); |
signal wire_framer_data_valid: std_logic; |
signal wire_coder_data: std_logic_vector(FRAME_OUTPUT_SIZE-1 downto 0); |
signal wire_coder_data_valid: std_logic; |
|
-- components instanciation and mapping |
begin |
|
tx_datalink_framer_0: ccsds_tx_framer |
generic map( |
CCSDS_TX_FRAMER_HEADER_LENGTH => CCSDS_TX_DATALINK_HEADER_LENGTH, |
CCSDS_TX_FRAMER_DATA_LENGTH => CCSDS_TX_DATALINK_DATA_LENGTH, |
CCSDS_TX_FRAMER_FOOTER_LENGTH => CCSDS_TX_DATALINK_FOOTER_LENGTH, |
CCSDS_TX_FRAMER_DATA_BUS_SIZE => CCSDS_TX_DATALINK_DATA_BUS_SIZE |
) |
port map( |
clk_i => clk_dat_i, |
rst_i => rst_i, |
dat_val_i => dat_val_i, |
dat_i => dat_i, |
dat_val_o => wire_framer_data_valid, |
dat_nxt_o => dat_nxt_o, |
dat_o => wire_framer_data, |
idl_o => idl_o |
); |
tx_datalink_coder_0: ccsds_tx_coder |
generic map( |
CCSDS_TX_CODER_ASM_LENGTH => CCSDS_TX_DATALINK_ASM_LENGTH, |
CCSDS_TX_CODER_DATA_BUS_SIZE => (CCSDS_TX_DATALINK_DATA_LENGTH+CCSDS_TX_DATALINK_HEADER_LENGTH+CCSDS_TX_DATALINK_FOOTER_LENGTH)*8, |
CCSDS_TX_CODER_DIFFERENTIAL_BITS_PER_CODEWORD => CCSDS_TX_DATALINK_CODER_DIFFERENTIAL_BITS_PER_CODEWORD, |
CCSDS_TX_CODER_DIFFERENTIAL_ENABLED => CCSDS_TX_DATALINK_CODER_DIFFERENTIAL_ENABLED |
) |
port map( |
clk_i => clk_dat_i, |
dat_i => wire_framer_data, |
dat_val_i => wire_framer_data_valid, |
rst_i => rst_i, |
dat_val_o => wire_coder_data_valid, |
dat_o => wire_coder_data |
); |
-- presynthesis checks |
-- internal processing |
--============================================================================= |
-- Begin of bitsoutputp |
-- Generate valid bits output word by word on coder data_valid signal |
--============================================================================= |
-- read: rst_i, wire_coder_data_valid |
-- write: dat_val_o |
-- r/w: |
BITSVALIDP: process (clk_dat_i) |
begin |
-- on each clock rising edge |
if rising_edge(clk_dat_i) then |
-- reset signal received |
if (rst_i = '1') then |
dat_val_o <= '0'; |
else |
if (wire_coder_data_valid = '1') then |
dat_val_o <= '1'; |
end if; |
end if; |
end if; |
end process; |
--============================================================================= |
-- Begin of bitsoutputp |
-- Generate bits output word by word based on coder output |
--============================================================================= |
-- read: rst_i, wire_coder_data |
-- write: dat_o |
-- r/w: |
BITSOUTPUTP: process (clk_bit_i) |
variable next_word_pointer : integer range 0 to FRAME_OUTPUT_WORDS := FRAME_OUTPUT_WORDS - 1; |
variable current_frame: std_logic_vector(FRAME_OUTPUT_SIZE-CCSDS_TX_DATALINK_DATA_BUS_SIZE-1 downto 0) := (others => '0'); |
begin |
-- on each clock rising edge |
if rising_edge(clk_bit_i) then |
-- reset signal received |
if (rst_i = '1') then |
next_word_pointer := FRAME_OUTPUT_WORDS - 1; |
dat_o <= (others => '0'); |
else |
-- generating valid bits output words |
if (next_word_pointer = FRAME_OUTPUT_WORDS - 1) then |
current_frame := wire_coder_data(FRAME_OUTPUT_SIZE-CCSDS_TX_DATALINK_DATA_BUS_SIZE-1 downto 0); |
dat_o <= wire_coder_data(FRAME_OUTPUT_SIZE-1 downto FRAME_OUTPUT_SIZE-CCSDS_TX_DATALINK_DATA_BUS_SIZE); |
next_word_pointer := FRAME_OUTPUT_WORDS - 2; |
else |
dat_o <= current_frame((next_word_pointer+1)*CCSDS_TX_DATALINK_DATA_BUS_SIZE-1 downto next_word_pointer*CCSDS_TX_DATALINK_DATA_BUS_SIZE); |
if (next_word_pointer = 0) then |
next_word_pointer := FRAME_OUTPUT_WORDS - 1; |
else |
next_word_pointer := next_word_pointer - 1; |
end if; |
end if; |
end if; |
end if; |
end process; |
end structure; |
/ccsds_tx_filter.vhd
0,0 → 1,210
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_tx_filter |
---- Version: 1.0.0 |
---- Description: |
---- Transform symbols to samples, oversample signal and filter it with SRRC filter |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/11/06: initial release |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary tx filter inputs and outputs |
--============================================================================= |
entity ccsds_tx_filter is |
generic( |
constant CCSDS_TX_FILTER_BITS_PER_SYMBOL: integer; -- in bits |
constant CCSDS_TX_FILTER_OVERSAMPLING_RATIO: integer; |
constant CCSDS_TX_FILTER_OFFSET_IQ: boolean := true; |
constant CCSDS_TX_FILTER_MODULATION_TYPE: integer; |
constant CCSDS_TX_FILTER_SIG_QUANT_DEPTH: integer; |
constant CCSDS_TX_FILTER_TARGET_SNR: real := 40.0 |
); |
port( |
-- inputs |
clk_i: in std_logic; |
rst_i: in std_logic; |
sym_i_i: in std_logic_vector(CCSDS_TX_FILTER_BITS_PER_SYMBOL-1 downto 0); |
sym_q_i: in std_logic_vector(CCSDS_TX_FILTER_BITS_PER_SYMBOL-1 downto 0); |
sym_val_i: in std_logic; |
-- outputs |
sam_i_o: out std_logic_vector(CCSDS_TX_FILTER_SIG_QUANT_DEPTH-1 downto 0); |
sam_q_o: out std_logic_vector(CCSDS_TX_FILTER_SIG_QUANT_DEPTH-1 downto 0); |
sam_val_o: out std_logic |
); |
end ccsds_tx_filter; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture structure of ccsds_tx_filter is |
component ccsds_tx_mapper_symbols_samples is |
generic( |
constant CCSDS_TX_MAPPER_TARGET_SNR: real; |
constant CCSDS_TX_MAPPER_BITS_PER_SYMBOL: integer; |
constant CCSDS_TX_MAPPER_QUANTIZATION_DEPTH: integer |
); |
port( |
clk_i: in std_logic; |
rst_i: in std_logic; |
sym_i: in std_logic_vector(CCSDS_TX_MAPPER_BITS_PER_SYMBOL-1 downto 0); |
sym_val_i: in std_logic; |
sam_val_o: out std_logic; |
sam_o: out std_logic_vector(CCSDS_TX_MAPPER_QUANTIZATION_DEPTH-1 downto 0) |
); |
end component; |
component ccsds_rxtx_oversampler is |
generic( |
CCSDS_RXTX_OVERSAMPLER_OVERSAMPLING_RATIO: integer; |
CCSDS_RXTX_OVERSAMPLER_SYMBOL_DEPHASING: boolean; |
CCSDS_RXTX_OVERSAMPLER_SIG_QUANT_DEPTH: integer |
); |
port( |
clk_i: in std_logic; |
sam_i: in std_logic_vector(CCSDS_RXTX_OVERSAMPLER_SIG_QUANT_DEPTH-1 downto 0); |
sam_val_i: in std_logic; |
rst_i: in std_logic; |
sam_o: out std_logic_vector(CCSDS_RXTX_OVERSAMPLER_SIG_QUANT_DEPTH-1 downto 0); |
sam_val_o: out std_logic |
); |
end component; |
component ccsds_rxtx_srrc is |
generic( |
CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO: integer; |
CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH: integer |
); |
port( |
clk_i: in std_logic; |
rst_i: in std_logic; |
sam_i: in std_logic_vector(CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH-1 downto 0); |
sam_val_i: in std_logic; |
sam_o: out std_logic_vector(CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH-1 downto 0); |
sam_val_o: out std_logic |
); |
end component; |
-- internal constants |
-- internal variable signals |
signal wire_sam_i: std_logic_vector(CCSDS_TX_FILTER_SIG_QUANT_DEPTH-1 downto 0); |
signal wire_sam_q: std_logic_vector(CCSDS_TX_FILTER_SIG_QUANT_DEPTH-1 downto 0); |
signal wire_sam_i_val: std_logic := '0'; |
signal wire_sam_q_val: std_logic := '0'; |
signal wire_sam_i_osr: std_logic_vector(CCSDS_TX_FILTER_SIG_QUANT_DEPTH-1 downto 0); |
signal wire_sam_q_osr: std_logic_vector(CCSDS_TX_FILTER_SIG_QUANT_DEPTH-1 downto 0); |
signal wire_sam_i_osr_val: std_logic; |
signal wire_sam_q_osr_val: std_logic; |
signal wire_sam_i_srrc_val: std_logic; |
signal wire_sam_q_srrc_val: std_logic; |
-- components instanciation and mapping |
begin |
tx_mapper_symbols_samples_i_0: ccsds_tx_mapper_symbols_samples |
generic map( |
CCSDS_TX_MAPPER_QUANTIZATION_DEPTH => CCSDS_TX_FILTER_SIG_QUANT_DEPTH, |
CCSDS_TX_MAPPER_TARGET_SNR => CCSDS_TX_FILTER_TARGET_SNR, |
CCSDS_TX_MAPPER_BITS_PER_SYMBOL => CCSDS_TX_FILTER_BITS_PER_SYMBOL |
) |
port map( |
clk_i => clk_i, |
sym_i => sym_i_i, |
sym_val_i => sym_val_i, |
rst_i => rst_i, |
sam_o => wire_sam_i, |
sam_val_o => wire_sam_i_val |
); |
tx_oversampler_i_0: ccsds_rxtx_oversampler |
generic map( |
CCSDS_RXTX_OVERSAMPLER_OVERSAMPLING_RATIO => CCSDS_TX_FILTER_OVERSAMPLING_RATIO, |
CCSDS_RXTX_OVERSAMPLER_SYMBOL_DEPHASING => CCSDS_TX_FILTER_OFFSET_IQ, |
CCSDS_RXTX_OVERSAMPLER_SIG_QUANT_DEPTH => CCSDS_TX_FILTER_SIG_QUANT_DEPTH |
) |
port map( |
clk_i => clk_i, |
sam_i => wire_sam_i, |
sam_val_i => wire_sam_i_val, |
rst_i => rst_i, |
sam_val_o => wire_sam_i_osr_val, |
sam_o => wire_sam_i_osr |
); |
tx_srrc_i_0: ccsds_rxtx_srrc |
generic map( |
CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO => CCSDS_TX_FILTER_OVERSAMPLING_RATIO, |
CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH => CCSDS_TX_FILTER_SIG_QUANT_DEPTH |
) |
port map( |
clk_i => clk_i, |
sam_i => wire_sam_i_osr, |
sam_val_i => wire_sam_i_osr_val, |
rst_i => rst_i, |
sam_o => sam_i_o, |
sam_val_o => wire_sam_i_srrc_val |
); |
-- BPSK |
BPSK_GENERATION: if (CCSDS_TX_FILTER_BITS_PER_SYMBOL = 1) and (CCSDS_TX_FILTER_MODULATION_TYPE = 2) generate |
sam_q_o <= (others => '0'); |
wire_sam_q_srrc_val <= '1'; |
end generate BPSK_GENERATION; |
-- nPSK |
NPSK_GENERATION: if (CCSDS_TX_FILTER_MODULATION_TYPE /= 2) or (CCSDS_TX_FILTER_BITS_PER_SYMBOL /= 1) generate |
tx_mapper_symbols_samples_q_0: ccsds_tx_mapper_symbols_samples |
generic map( |
CCSDS_TX_MAPPER_QUANTIZATION_DEPTH => CCSDS_TX_FILTER_SIG_QUANT_DEPTH, |
CCSDS_TX_MAPPER_TARGET_SNR => CCSDS_TX_FILTER_TARGET_SNR, |
CCSDS_TX_MAPPER_BITS_PER_SYMBOL => CCSDS_TX_FILTER_BITS_PER_SYMBOL |
) |
port map( |
clk_i => clk_i, |
sym_i => sym_q_i, |
sym_val_i => sym_val_i, |
rst_i => rst_i, |
sam_o => wire_sam_q, |
sam_val_o => wire_sam_q_val |
); |
tx_oversampler_q_0: ccsds_rxtx_oversampler |
generic map( |
CCSDS_RXTX_OVERSAMPLER_OVERSAMPLING_RATIO => CCSDS_TX_FILTER_OVERSAMPLING_RATIO, |
CCSDS_RXTX_OVERSAMPLER_SYMBOL_DEPHASING => false, |
CCSDS_RXTX_OVERSAMPLER_SIG_QUANT_DEPTH => CCSDS_TX_FILTER_SIG_QUANT_DEPTH |
) |
port map( |
clk_i => clk_i, |
sam_i => wire_sam_q, |
sam_val_i => wire_sam_q_val, |
rst_i => rst_i, |
sam_val_o => wire_sam_q_osr_val, |
sam_o => wire_sam_q_osr |
); |
tx_srrc_q_0: ccsds_rxtx_srrc |
generic map( |
CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO => CCSDS_TX_FILTER_OVERSAMPLING_RATIO, |
CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH => CCSDS_TX_FILTER_SIG_QUANT_DEPTH |
) |
port map( |
clk_i => clk_i, |
sam_i => wire_sam_q_osr, |
sam_val_i => wire_sam_q_osr_val, |
rst_i => rst_i, |
sam_o => sam_q_o, |
sam_val_o => wire_sam_q_srrc_val |
); |
end generate NPSK_GENERATION; |
--Valid samples indicator |
sam_val_o <= wire_sam_i_srrc_val and wire_sam_q_srrc_val; |
-- presynthesis checks |
CHKFILTERP0: if (CCSDS_TX_FILTER_BITS_PER_SYMBOL > 2*(CCSDS_TX_FILTER_SIG_QUANT_DEPTH-1)) generate |
process |
begin |
report "ERROR: BITS PER SYMBOL CANNOT BE HIGHER THAN 2*(CCSDS_TX_FILTER_SIG_QUANT_DEPTH-1)" severity failure; |
wait; |
end process; |
end generate CHKFILTERP0; |
end structure; |
/ccsds_tx_footer.vhd
0,0 → 1,93
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_tx_footer |
---- Version: 1.0.0 |
---- Description: |
---- TBD |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/02/28: initial release |
---- 2016/10/21: rework |
------------------------------- |
--TODO: operationnal control field |
--TODO: security trailer |
--[OPT] SECURITY TRAILER |
--[OPT] TRANSFER FRAME TRAILER (2 to 6 octets) |
-- \ [OPT] OPERATIONAL CONTROL FIELD => 4 octets |
-- \ [OPT] Frame error control field => 2 octets |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary tx footer inputs and outputs |
--============================================================================= |
entity ccsds_tx_footer is |
generic( |
constant CCSDS_TX_FOOTER_DATA_LENGTH: integer; -- in Bytes |
constant CCSDS_TX_FOOTER_LENGTH: integer -- in Bytes |
); |
port( |
-- inputs |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_FOOTER_DATA_LENGTH*8-1 downto 0); |
nxt_i: in std_logic; |
rst_i: in std_logic; |
-- outputs |
bus_o: out std_logic; |
dat_o: out std_logic_vector((CCSDS_TX_FOOTER_DATA_LENGTH+CCSDS_TX_FOOTER_LENGTH)*8-1 downto 0); |
dat_val_o: out std_logic |
); |
end ccsds_tx_footer; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture structure of ccsds_tx_footer is |
component ccsds_rxtx_crc is |
generic( |
constant CCSDS_RXTX_CRC_LENGTH: integer; |
constant CCSDS_RXTX_CRC_DATA_LENGTH: integer |
); |
port( |
clk_i: in std_logic; |
rst_i: in std_logic; |
nxt_i: in std_logic; |
pad_dat_i: in std_logic_vector(CCSDS_RXTX_CRC_LENGTH*8-1 downto 0); |
pad_dat_val_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_RXTX_CRC_DATA_LENGTH*8-1 downto 0); |
bus_o: out std_logic; |
crc_o: out std_logic_vector(CCSDS_RXTX_CRC_LENGTH*8-1 downto 0); |
dat_o: out std_logic_vector(CCSDS_RXTX_CRC_DATA_LENGTH*8-1 downto 0); |
dat_val_o: out std_logic |
); |
end component; |
-- internal variable signals |
-- components instanciation and mapping |
begin |
tx_footer_crc_0: ccsds_rxtx_crc |
generic map( |
CCSDS_RXTX_CRC_DATA_LENGTH => CCSDS_TX_FOOTER_DATA_LENGTH, |
CCSDS_RXTX_CRC_LENGTH => CCSDS_TX_FOOTER_LENGTH |
) |
port map( |
clk_i => clk_i, |
rst_i => rst_i, |
nxt_i => nxt_i, |
pad_dat_i => (others => '0'), |
pad_dat_val_i => '0', |
bus_o => bus_o, |
dat_i => dat_i, |
crc_o => dat_o(CCSDS_TX_FOOTER_LENGTH*8-1 downto 0), |
dat_o => dat_o((CCSDS_TX_FOOTER_DATA_LENGTH+CCSDS_TX_FOOTER_LENGTH)*8-1 downto CCSDS_TX_FOOTER_LENGTH*8), |
dat_val_o => dat_val_o |
); |
-- internal processing |
end structure; |
/ccsds_tx_framer.vhd
0,0 → 1,363
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_tx_framer |
---- Version: 1.0.0 |
---- Description: |
---- Implementation of standard CCSDS 132.0-B-2 |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/02/27: initial release |
---- 2016/10/20: rework |
---- 2016/10/24: multiple footers generation to ensure higher speed than input max data rate (CCSDS_TX_FRAMER_DATA_BUS_SIZE*CLK_FREQ bits/sec) |
---- 2016/10/31: ressources optimization |
---- 2016/11/03: add only idle data insertion |
------------------------------- |
--TODO: trailer as option |
--HEADER (6 up to 70 bytes) / before data / f(idle) |
--TRANSFER FRAME DATA FIELD => Variable |
--TRAILER (2 up to 6 bytes) / after data / f(data, header) |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary tx framer inputs and outputs |
--============================================================================= |
entity ccsds_tx_framer is |
generic( |
constant CCSDS_TX_FRAMER_DATA_BUS_SIZE: integer; -- in bits |
constant CCSDS_TX_FRAMER_DATA_LENGTH: integer; -- in Bytes |
constant CCSDS_TX_FRAMER_FOOTER_LENGTH: integer; -- in Bytes |
constant CCSDS_TX_FRAMER_HEADER_LENGTH: integer; -- in Bytes |
constant CCSDS_TX_FRAMER_PARALLELISM_MAX_RATIO: integer := 16 -- activated max framer parallelism speed ratio / 1 = full speed / 2 = wishbone bus non-pipelined write max speed / ... / CCSDS_TX_FRAMER_DATA_BUS_SIZE = external serial data |
); |
port( |
-- inputs |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_FRAMER_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
-- outputs |
dat_o: out std_logic_vector((CCSDS_TX_FRAMER_HEADER_LENGTH+CCSDS_TX_FRAMER_FOOTER_LENGTH+CCSDS_TX_FRAMER_DATA_LENGTH)*8-1 downto 0); |
dat_nxt_o: out std_logic; |
dat_val_o: out std_logic; |
idl_o: out std_logic |
); |
end ccsds_tx_framer; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture structure of ccsds_tx_framer is |
component ccsds_tx_header is |
generic( |
constant CCSDS_TX_HEADER_LENGTH: integer |
); |
port( |
clk_i: in std_logic; |
idl_i: in std_logic; |
nxt_i: in std_logic; |
rst_i: in std_logic; |
dat_o: out std_logic_vector(CCSDS_TX_HEADER_LENGTH*8-1 downto 0); |
dat_val_o: out std_logic |
); |
end component; |
component ccsds_tx_footer is |
generic( |
constant CCSDS_TX_FOOTER_DATA_LENGTH : integer; |
constant CCSDS_TX_FOOTER_LENGTH: integer |
); |
port( |
clk_i: in std_logic; |
rst_i: in std_logic; |
nxt_i: in std_logic; |
bus_o: out std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_FOOTER_DATA_LENGTH*8-1 downto 0); |
dat_o: out std_logic_vector((CCSDS_TX_FOOTER_LENGTH+CCSDS_TX_FOOTER_DATA_LENGTH)*8-1 downto 0); |
dat_val_o: out std_logic |
); |
end component; |
|
-- internal constants |
constant CCSDS_TX_FRAMER_FOOTER_NUMBER : integer := CCSDS_TX_FRAMER_DATA_BUS_SIZE*((CCSDS_TX_FRAMER_HEADER_LENGTH+CCSDS_TX_FRAMER_DATA_LENGTH+CCSDS_TX_FRAMER_FOOTER_LENGTH)*8+1)/(CCSDS_TX_FRAMER_DATA_LENGTH*8*CCSDS_TX_FRAMER_PARALLELISM_MAX_RATIO)+1; -- 8*(HEAD+DATA+FOOT+1) clks / crc ; BUS bits / parallelism * clk ; DATA*8 bits / footer |
constant CCSDS_TX_FRAMER_OID_PATTERN: std_logic_vector(CCSDS_TX_FRAMER_DATA_LENGTH*8-1 downto 0) := (others => '1'); -- Only Idle Data Pattern transmitted (jam payload for frame stuffing) |
|
-- internal variable signals |
type frame_array is array (CCSDS_TX_FRAMER_FOOTER_NUMBER-1 downto 0) of std_logic_vector((CCSDS_TX_FRAMER_FOOTER_LENGTH+CCSDS_TX_FRAMER_DATA_LENGTH+CCSDS_TX_FRAMER_HEADER_LENGTH)*8-1 downto 0); |
signal wire_header_data: std_logic_vector(CCSDS_TX_FRAMER_HEADER_LENGTH*8-1 downto 0); |
signal wire_footer_data_o: frame_array; |
signal wire_header_data_valid: std_logic; |
signal wire_footer_data_valid: std_logic_vector(CCSDS_TX_FRAMER_FOOTER_NUMBER-1 downto 0); |
signal wire_header_next: std_logic := '0'; |
signal wire_header_idle: std_logic := '0'; |
signal wire_footer_next: std_logic_vector(CCSDS_TX_FRAMER_FOOTER_NUMBER-1 downto 0) := (others => '0'); |
signal wire_footer_busy: std_logic_vector(CCSDS_TX_FRAMER_FOOTER_NUMBER-1 downto 0); |
|
signal reg_next_frame: std_logic_vector(CCSDS_TX_FRAMER_DATA_LENGTH*8-CCSDS_TX_FRAMER_DATA_BUS_SIZE-1 downto 0); |
signal reg_current_frame: std_logic_vector((CCSDS_TX_FRAMER_DATA_LENGTH)*8-1 downto 0); |
signal reg_processing_frame: std_logic_vector((CCSDS_TX_FRAMER_DATA_LENGTH+CCSDS_TX_FRAMER_HEADER_LENGTH)*8-1 downto 0); |
signal next_processing_frame_pointer : integer range 0 to CCSDS_TX_FRAMER_FOOTER_NUMBER-1 := 0; |
|
-- components instanciation and mapping |
begin |
tx_header_0: ccsds_tx_header |
generic map( |
CCSDS_TX_HEADER_LENGTH => CCSDS_TX_FRAMER_HEADER_LENGTH |
) |
port map( |
clk_i => clk_i, |
idl_i => wire_header_idle, |
nxt_i => wire_header_next, |
rst_i => rst_i, |
dat_o => wire_header_data, |
dat_val_o => wire_header_data_valid |
); |
|
FOOTERGEN: |
for i in 0 to CCSDS_TX_FRAMER_FOOTER_NUMBER-1 generate |
tx_footer_x : ccsds_tx_footer |
generic map( |
CCSDS_TX_FOOTER_DATA_LENGTH => CCSDS_TX_FRAMER_DATA_LENGTH+CCSDS_TX_FRAMER_HEADER_LENGTH, |
CCSDS_TX_FOOTER_LENGTH => CCSDS_TX_FRAMER_FOOTER_LENGTH |
) |
port map( |
clk_i => clk_i, |
rst_i => rst_i, |
nxt_i => wire_footer_next(i), |
bus_o => wire_footer_busy(i), |
dat_i => reg_processing_frame, |
dat_o => wire_footer_data_o(i), |
dat_val_o => wire_footer_data_valid(i) |
); |
end generate FOOTERGEN; |
|
-- presynthesis checks |
CHKFRAMERP0 : if ((CCSDS_TX_FRAMER_DATA_LENGTH*8) mod CCSDS_TX_FRAMER_DATA_BUS_SIZE /= 0) generate |
process |
begin |
report "ERROR: FRAMER DATA LENGTH SHOULD BE A MULTIPLE OF FRAMER DATA BUS SIZE" severity failure; |
wait; |
end process; |
end generate CHKFRAMERP0; |
CHKFRAMERP1 : if ((CCSDS_TX_FRAMER_DATA_LENGTH) = 0) generate |
process |
begin |
report "ERROR: FRAMER DATA LENGTH CANNOT BE 0" severity failure; |
wait; |
end process; |
end generate CHKFRAMERP1; |
CHKFRAMERP2 : if ((CCSDS_TX_FRAMER_PARALLELISM_MAX_RATIO) = 0) generate |
process |
begin |
report "ERROR: PARALLELISM MAX RATIO CANNOT BE 0" severity failure; |
wait; |
end process; |
end generate CHKFRAMERP2; |
|
-- internal processing |
|
--============================================================================= |
-- Begin of frameroutputp |
-- Generate valid frame output on footer data_valid signal |
--============================================================================= |
-- read: rst_i, wire_footer_data, wire_footer_data_valid |
-- write: dat_o, dat_val_o |
-- r/w: next_valid_frame_pointer |
FRAMEROUTPUTP: process (clk_i) |
variable next_valid_frame_pointer : integer range 0 to CCSDS_TX_FRAMER_FOOTER_NUMBER-1 := 0; |
begin |
-- on each clock rising edge |
if rising_edge(clk_i) then |
-- reset signal received |
if (rst_i = '1') then |
next_valid_frame_pointer := 0; |
dat_o <= (others => '0'); |
dat_val_o <= '0'; |
-- generating valid frames output |
else |
dat_o <= wire_footer_data_o(next_valid_frame_pointer); |
if (wire_footer_data_valid(next_valid_frame_pointer) = '1') then |
dat_val_o <= '1'; |
if (next_valid_frame_pointer < (CCSDS_TX_FRAMER_FOOTER_NUMBER-1)) then |
next_valid_frame_pointer := (next_valid_frame_pointer + 1); |
else |
next_valid_frame_pointer := 0; |
end if; |
else |
dat_o <= (others => '0'); |
dat_val_o <= '0'; |
end if; |
end if; |
end if; |
end process; |
--============================================================================= |
-- Begin of framerprocessp |
-- Start footer computation on valid header signal |
--============================================================================= |
-- read: wire_header_data, wire_header_data_valid |
-- write: next_processing_frame_pointer, reg_processing_frame, wire_footer_next |
-- r/w: |
FRAMERPROCESSP: process (clk_i) |
variable reg_next_processing_frame: std_logic_vector((CCSDS_TX_FRAMER_DATA_LENGTH)*8-1 downto 0); |
begin |
-- on each clock rising edge |
if rising_edge(clk_i) then |
-- reset signal received |
if (rst_i = '1') then |
next_processing_frame_pointer <= 0; |
wire_footer_next <= (others => '0'); |
else |
if(wire_header_data_valid = '1') then |
reg_processing_frame((CCSDS_TX_FRAMER_DATA_LENGTH+CCSDS_TX_FRAMER_HEADER_LENGTH)*8-1 downto CCSDS_TX_FRAMER_DATA_LENGTH*8) <= wire_header_data; |
-- idle data to be used |
if (wire_header_data(10 downto 0) = "11111111110") then |
reg_processing_frame(CCSDS_TX_FRAMER_DATA_LENGTH*8-1 downto 0) <= CCSDS_TX_FRAMER_OID_PATTERN; |
reg_next_processing_frame := reg_current_frame; |
-- current data to be used |
else |
-- continuous data flow header is one clk in advance |
if (CCSDS_TX_FRAMER_DATA_LENGTH*8 = CCSDS_TX_FRAMER_DATA_BUS_SIZE) and (CCSDS_TX_FRAMER_PARALLELISM_MAX_RATIO = 1) then |
reg_processing_frame(CCSDS_TX_FRAMER_DATA_LENGTH*8-1 downto 0) <= reg_next_processing_frame; |
reg_next_processing_frame := reg_current_frame; |
-- header is synchronous with data |
else |
reg_processing_frame(CCSDS_TX_FRAMER_DATA_LENGTH*8-1 downto 0) <= reg_current_frame; |
end if; |
end if; |
wire_footer_next(next_processing_frame_pointer) <= '1'; |
if (next_processing_frame_pointer = CCSDS_TX_FRAMER_FOOTER_NUMBER-1) then |
next_processing_frame_pointer <= 0; |
else |
next_processing_frame_pointer <= (next_processing_frame_pointer + 1); |
end if; |
end if; |
if (next_processing_frame_pointer = 0) then |
wire_footer_next(CCSDS_TX_FRAMER_FOOTER_NUMBER-1) <= '0'; |
else |
wire_footer_next(next_processing_frame_pointer-1) <= '0'; |
end if; |
end if; |
end if; |
end process; |
--============================================================================= |
-- Begin of framergeneratep |
-- Generate next_frame, start next header generation |
--============================================================================= |
-- read: dat_val_i, rst_i |
-- write: wire_header_next, reg_current_frame, reg_next_frame, dat_nxt_o, idl_o |
-- r/w: |
FRAMERGENERATEP: process (clk_i) |
variable next_frame_write_pos: integer range 0 to (CCSDS_TX_FRAMER_DATA_LENGTH*8/CCSDS_TX_FRAMER_DATA_BUS_SIZE)-1 := (CCSDS_TX_FRAMER_DATA_LENGTH*8/CCSDS_TX_FRAMER_DATA_BUS_SIZE)-1; |
variable frame_output_counter: integer range 0 to (CCSDS_TX_FRAMER_DATA_LENGTH*CCSDS_TX_FRAMER_PARALLELISM_MAX_RATIO*8/CCSDS_TX_FRAMER_DATA_BUS_SIZE)-1 := 0; |
variable current_frame_ready: std_logic := '0'; |
begin |
-- on each clock rising edge |
if rising_edge(clk_i) then |
-- reset signal received |
if (rst_i = '1') then |
current_frame_ready := '0'; |
wire_header_next <= '0'; |
next_frame_write_pos := (CCSDS_TX_FRAMER_DATA_LENGTH*8/CCSDS_TX_FRAMER_DATA_BUS_SIZE)-1; |
frame_output_counter := 0; |
idl_o <= '0'; |
dat_nxt_o <= '0'; |
else |
-- valid data is presented |
if (dat_val_i = '1') then |
-- next frame is full |
if (next_frame_write_pos = 0) then |
reg_current_frame(CCSDS_TX_FRAMER_DATA_BUS_SIZE-1 downto 0) <= dat_i; |
reg_current_frame(CCSDS_TX_FRAMER_DATA_LENGTH*8-1 downto CCSDS_TX_FRAMER_DATA_BUS_SIZE) <= reg_next_frame; |
-- time to start frame computation |
if (frame_output_counter = 0) then |
-- CRC is ready to compute |
if (wire_footer_busy(next_processing_frame_pointer) = '0') then |
frame_output_counter := (CCSDS_TX_FRAMER_DATA_LENGTH*8*CCSDS_TX_FRAMER_PARALLELISM_MAX_RATIO/CCSDS_TX_FRAMER_DATA_BUS_SIZE)-1; |
wire_header_next <= '1'; |
wire_header_idle <= '0'; |
idl_o <= '0'; |
-- source data rate overflow / stop buffer output |
else |
dat_nxt_o <= '0'; |
end if; |
else |
frame_output_counter := frame_output_counter - 1; |
-- signal a frame ready for computation |
if (current_frame_ready = '0') then |
wire_header_next <= '0'; |
current_frame_ready := '1'; |
-- source data rate overflow |
else |
dat_nxt_o <= '0'; |
end if; |
end if; |
next_frame_write_pos := CCSDS_TX_FRAMER_DATA_LENGTH*8/CCSDS_TX_FRAMER_DATA_BUS_SIZE-1; |
else |
-- filling next frame |
reg_next_frame(next_frame_write_pos*CCSDS_TX_FRAMER_DATA_BUS_SIZE-1 downto (next_frame_write_pos-1)*CCSDS_TX_FRAMER_DATA_BUS_SIZE) <= dat_i; |
next_frame_write_pos := next_frame_write_pos-1; |
-- time to start frame computation |
if (frame_output_counter = 0) then |
-- CRC is ready to compute |
if (wire_footer_busy(next_processing_frame_pointer) = '0') then |
dat_nxt_o <= '1'; |
frame_output_counter := (CCSDS_TX_FRAMER_DATA_LENGTH*CCSDS_TX_FRAMER_PARALLELISM_MAX_RATIO*8/CCSDS_TX_FRAMER_DATA_BUS_SIZE)-1; |
-- no frame is ready / inserting idle data |
if (current_frame_ready = '0') then |
wire_header_next <= '1'; |
wire_header_idle <= '1'; |
idl_o <= '1'; |
-- a frame is ready |
else |
wire_header_next <= '1'; |
wire_header_idle <= '0'; |
current_frame_ready := '0'; |
idl_o <= '0'; |
end if; |
else |
dat_nxt_o <= '0'; |
end if; |
else |
-- stop data before overflow |
if (next_frame_write_pos = 1) and (current_frame_ready = '1') then |
dat_nxt_o <= '0'; |
end if; |
frame_output_counter := frame_output_counter - 1; |
wire_header_next <= '0'; |
end if; |
end if; |
-- no valid data |
else |
-- time to start frame computation |
if (frame_output_counter = 0) then |
-- CRC is ready to compute |
if (wire_footer_busy(next_processing_frame_pointer) = '0') then |
dat_nxt_o <= '1'; |
frame_output_counter := (CCSDS_TX_FRAMER_DATA_LENGTH*CCSDS_TX_FRAMER_PARALLELISM_MAX_RATIO*8/CCSDS_TX_FRAMER_DATA_BUS_SIZE)-1; |
if (current_frame_ready = '0') then |
wire_header_next <= '1'; |
wire_header_idle <= '1'; |
idl_o <= '1'; |
else |
wire_header_next <= '1'; |
wire_header_idle <= '0'; |
current_frame_ready := '0'; |
idl_o <= '0'; |
end if; |
end if; |
else |
wire_header_next <= '0'; |
frame_output_counter := frame_output_counter - 1; |
end if; |
end if; |
end if; |
end if; |
end process; |
end structure; |
/ccsds_tx_header.vhd
0,0 → 1,159
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_tx_header |
---- Version: 1.0.0 |
---- Description: |
---- TBD |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/02/28: initial release |
---- 2016/10/21: rework |
---- 2016/11/03: add idle data flag |
------------------------------- |
--TODO: static fixed virtual channel now - implement virtual channel service |
--TODO: secondary header |
--TODO: security header |
|
--TRANSFER FRAME PRIMARY HEADER => 6 octets |
-- \ MASTER CHANNEL ID => 12 bits |
-- \ TRANSFER FRAME VERSION NUMBER => 2 bits |
-- \ SPACECRAFT ID => 10 bits |
-- \ VIRTUAL CHANNEL ID => 3 bits |
-- \ OCF FLAG => 1 bit |
-- \ MASTER CHANNEL FRAME COUNT => 1 octet |
-- \ VIRTUAL CHANNEL FRAME COUNT => 1 octet |
-- \ TRANSFER FRAME DATA FIELD STATUS => 2 octets |
-- \ TRANSFER FRAME SECONDARY HEADER FLAG => 1 bit |
-- \ SYNC FLAG => 1 bit |
-- \ PACKET ORDER FLAG => 1 bit |
-- \ SEGMENT LENGTH ID => 2 bits |
-- \ FIRST HEADER POINTER => 11 bits |
--[OPT] TRANSFER FRAME SECONDARY HEADER => up to 64 octets |
-- \ TRANSFER FRAME SECONDARY HEADER ID => 1 octet |
-- \ TRANSFER FRAME SECONDARY HEADER VERSION NUMBER => 2 bits |
-- \ TRANSFER FRAME SECONDARY HEADER LENGTH => 6 bits |
-- \ TRANSFER FRAME SECONDARY HEADER DATA FIELD => up to 63 octets |
--[OPT] SECURITY HEADER |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary tx header inputs and outputs |
--============================================================================= |
entity ccsds_tx_header is |
generic( |
CCSDS_TX_HEADER_LENGTH: integer; -- in Bytes |
CCSDS_TX_HEADER_MCI_TFVN: std_logic_vector(2-1 downto 0) := "00"; -- Transfer Frame Version Number value |
CCSDS_TX_HEADER_MCI_SID: std_logic_vector(10-1 downto 0) := "1100110011"; -- Spacecraft ID value |
CCSDS_TX_HEADER_MCFC_LENGTH: integer := 8; -- Master Channel Frame Count length - in bits |
CCSDS_TX_HEADER_OCFF: std_logic := '0'; -- Operationnal Control Field Flag |
CCSDS_TX_HEADER_VCI: std_logic_vector(3-1 downto 0) := "000"; -- Virtual Channel Identifier value |
CCSDS_TX_HEADER_VCFC_LENGTH: integer := 8; -- Virtual Channel Frame Count length - in bits |
CCSDS_TX_HEADER_TFDFS_LENGTH: integer := 16; -- Transfer Frame Data Field Status length - in bits |
CCSDS_TX_HEADER_TFDFS_POF: std_logic := '0'; -- Packet Order Flag |
CCSDS_TX_HEADER_TFDFS_SF: std_logic := '0'; -- Synchronization Flag |
CCSDS_TX_HEADER_TFDFS_SLI: std_logic_vector(1 downto 0) := "11"; -- Segment Length Identifier |
CCSDS_TX_HEADER_TFDFS_TFSHF: std_logic := '0' -- Transfer Frame Secondary Header Flag |
); |
port( |
-- inputs |
clk_i: in std_logic; |
idl_i: in std_logic; |
nxt_i: in std_logic; |
rst_i: in std_logic; |
-- outputs |
dat_o: out std_logic_vector(CCSDS_TX_HEADER_LENGTH*8-1 downto 0); |
dat_val_o: out std_logic |
); |
end ccsds_tx_header; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture rtl of ccsds_tx_header is |
-- internal variable signals |
-- components instanciation and mapping |
begin |
|
-- presynthesis checks |
CHKHEADERP0 : if CCSDS_TX_HEADER_LENGTH*8 /= (CCSDS_TX_HEADER_MCI_TFVN'length + CCSDS_TX_HEADER_MCI_SID'length + CCSDS_TX_HEADER_VCI'length + CCSDS_TX_HEADER_MCFC_LENGTH + CCSDS_TX_HEADER_VCFC_LENGTH + CCSDS_TX_HEADER_TFDFS_LENGTH + 1) generate |
process |
begin |
report "ERROR: HEADER LENGTH IS DIFFERENT OF TOTAL SUBELEMENTS LENGTH" severity failure; |
wait; |
end process; |
end generate CHKHEADERP0; |
|
-- internal processing |
|
--============================================================================= |
-- Begin of headerp |
-- Generate valid headers |
--============================================================================= |
-- read: rst_i, nxt_i |
-- write: dat_val_o, dat_o |
-- r/w: |
HEADERP : process (clk_i) |
variable header_mci_tfvn: std_logic_vector(CCSDS_TX_HEADER_MCI_TFVN'length-1 downto 0) := CCSDS_TX_HEADER_MCI_TFVN; -- Transfer Frame Version Number |
variable header_mci_sid: std_logic_vector(CCSDS_TX_HEADER_MCI_SID'length-1 downto 0) := CCSDS_TX_HEADER_MCI_SID; -- Spacecraft ID |
variable header_vci: std_logic_vector(CCSDS_TX_HEADER_VCI'length-1 downto 0) := CCSDS_TX_HEADER_VCI; -- Virtual Channel Identifier |
variable header_ocff: std_logic := CCSDS_TX_HEADER_OCFF; -- Operationnal Control Field Flag |
variable header_mcfc: integer range 0 to (2**CCSDS_TX_HEADER_MCFC_LENGTH)-1 := 0; -- Master Channel Frame Count |
variable header_vcfc: integer range 0 to (2**CCSDS_TX_HEADER_VCFC_LENGTH)-1 := 0; -- Virtual Channel Frame Count |
variable header_tfdfs_fhp: std_logic_vector(CCSDS_TX_HEADER_TFDFS_LENGTH-6 downto 0) := "00000000000"; -- First Header Pointer / 11111111110 when idle data inside only |
begin |
-- on each clock rising edge |
if rising_edge(clk_i) then |
-- reset signal received |
if (rst_i = '1') then |
dat_o <= (others => '0'); |
dat_val_o <= '0'; |
header_mci_tfvn := CCSDS_TX_HEADER_MCI_TFVN; |
header_mci_sid := CCSDS_TX_HEADER_MCI_SID; |
header_vci := CCSDS_TX_HEADER_VCI; |
header_ocff := '1'; |
header_mcfc := 0; |
header_vcfc := 0; |
header_tfdfs_fhp := "00000000000"; |
else |
if (nxt_i = '1') then |
if(idl_i = '1') then |
header_tfdfs_fhp := "11111111110"; |
else |
header_tfdfs_fhp := "00000000000"; |
end if; |
dat_val_o <= '1'; |
dat_o(CCSDS_TX_HEADER_LENGTH*8-1 downto CCSDS_TX_HEADER_LENGTH*8-CCSDS_TX_HEADER_MCI_TFVN'length) <= header_mci_tfvn; |
dat_o(CCSDS_TX_HEADER_LENGTH*8-CCSDS_TX_HEADER_MCI_TFVN'length-1 downto CCSDS_TX_HEADER_LENGTH*8-CCSDS_TX_HEADER_MCI_TFVN'length-CCSDS_TX_HEADER_MCI_SID'length) <= header_mci_sid; |
dat_o(CCSDS_TX_HEADER_LENGTH*8-CCSDS_TX_HEADER_MCI_TFVN'length-CCSDS_TX_HEADER_MCI_SID'length-1 downto CCSDS_TX_HEADER_LENGTH*8-CCSDS_TX_HEADER_MCI_TFVN'length-CCSDS_TX_HEADER_MCI_SID'length-CCSDS_TX_HEADER_VCI'length) <= header_vci; |
dat_o(CCSDS_TX_HEADER_LENGTH*8-CCSDS_TX_HEADER_MCI_TFVN'length-CCSDS_TX_HEADER_MCI_SID'length-CCSDS_TX_HEADER_VCI'length-1) <= header_ocff; |
dat_o(CCSDS_TX_HEADER_LENGTH*8-CCSDS_TX_HEADER_MCI_TFVN'length-CCSDS_TX_HEADER_MCI_SID'length-CCSDS_TX_HEADER_VCI'length-1-1 downto CCSDS_TX_HEADER_LENGTH*8-CCSDS_TX_HEADER_MCI_TFVN'length-CCSDS_TX_HEADER_MCI_SID'length-CCSDS_TX_HEADER_VCI'length-1-CCSDS_TX_HEADER_MCFC_LENGTH) <= std_logic_vector(to_unsigned(header_mcfc,CCSDS_TX_HEADER_MCFC_LENGTH)); |
dat_o(CCSDS_TX_HEADER_LENGTH*8-CCSDS_TX_HEADER_MCI_TFVN'length-CCSDS_TX_HEADER_MCI_SID'length-CCSDS_TX_HEADER_VCI'length-1-CCSDS_TX_HEADER_MCFC_LENGTH-1 downto CCSDS_TX_HEADER_LENGTH*8-CCSDS_TX_HEADER_MCI_TFVN'length-CCSDS_TX_HEADER_MCI_SID'length-CCSDS_TX_HEADER_VCI'length-1-CCSDS_TX_HEADER_MCFC_LENGTH-CCSDS_TX_HEADER_VCFC_LENGTH) <= std_logic_vector(to_unsigned(header_vcfc,CCSDS_TX_HEADER_VCFC_LENGTH)); |
dat_o(CCSDS_TX_HEADER_TFDFS_LENGTH-1 downto CCSDS_TX_HEADER_TFDFS_LENGTH-5) <= CCSDS_TX_HEADER_TFDFS_TFSHF & CCSDS_TX_HEADER_TFDFS_SF & CCSDS_TX_HEADER_TFDFS_POF & CCSDS_TX_HEADER_TFDFS_SLI; |
dat_o(CCSDS_TX_HEADER_TFDFS_LENGTH-6 downto 0) <= header_tfdfs_fhp; |
if (header_mcfc = (2**CCSDS_TX_HEADER_MCFC_LENGTH)-1) then |
header_mcfc := 0; |
else |
header_mcfc := header_mcfc + 1; |
end if; |
if (header_vcfc = (2**CCSDS_TX_HEADER_VCFC_LENGTH)-1) then |
header_vcfc := 0; |
else |
header_vcfc := header_vcfc + 1; |
end if; |
else |
dat_val_o <= '0'; |
end if; |
end if; |
end if; |
end process; |
end rtl; |
/ccsds_tx_manager.vhd
0,0 → 1,203
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_tx_manager |
---- Version: 1.0.0 |
---- Description: |
---- In charge of internal clocks generation + forwarding to reduce power draw + select TX input data |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/10/16: initial release |
---- 2016/10/31: add serdes sub-component |
---- 2016/11/05: add clock generator sub-component |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary tx manager inputs and outputs |
--============================================================================= |
entity ccsds_tx_manager is |
generic( |
constant CCSDS_TX_MANAGER_BITS_PER_SYMBOL: integer; |
constant CCSDS_TX_MANAGER_MODULATION_TYPE: integer; |
constant CCSDS_TX_MANAGER_DATALINK_OVERHEAD_RATIO: integer := 2; |
constant CCSDS_TX_MANAGER_PARALLELISM_MAX_RATIO: integer := 16; |
constant CCSDS_TX_MANAGER_OVERSAMPLING_RATIO: integer; |
constant CCSDS_TX_MANAGER_DATA_BUS_SIZE : integer |
); |
port( |
-- inputs |
clk_i: in std_logic; |
dat_par_i: in std_logic_vector(CCSDS_TX_MANAGER_DATA_BUS_SIZE-1 downto 0); |
dat_ser_i: in std_logic; |
dat_val_i: in std_logic; |
ena_i: in std_logic; |
in_sel_i: in std_logic; -- 0 = parallel data / 1 = external serial data |
rst_i: in std_logic; |
-- outputs |
clk_bit_o: out std_logic; |
clk_dat_o: out std_logic; |
clk_sam_o: out std_logic; |
clk_sym_o: out std_logic; |
dat_o: out std_logic_vector(CCSDS_TX_MANAGER_DATA_BUS_SIZE-1 downto 0); |
dat_val_o: out std_logic; |
ena_o: out std_logic |
); |
end ccsds_tx_manager; |
|
--============================================================================= |
-- architecture declaration / internal connections |
--============================================================================= |
architecture structure of ccsds_tx_manager is |
component ccsds_rxtx_serdes is |
generic ( |
constant CCSDS_RXTX_SERDES_DEPTH : integer |
); |
port( |
clk_i: in std_logic; |
dat_par_i: in std_logic_vector(CCSDS_RXTX_SERDES_DEPTH-1 downto 0); |
dat_par_val_i: in std_logic; |
dat_ser_i: in std_logic; |
dat_ser_val_i: in std_logic; |
rst_i: in std_logic; |
bus_o: out std_logic; |
dat_par_o: out std_logic_vector(CCSDS_RXTX_SERDES_DEPTH-1 downto 0); |
dat_par_val_o: out std_logic; |
dat_ser_o: out std_logic; |
dat_ser_val_o: out std_logic |
); |
end component; |
component ccsds_rxtx_clock_divider is |
generic( |
CCSDS_RXTX_CLOCK_DIVIDER: integer |
); |
port( |
clk_i: in std_logic; |
rst_i: in std_logic; |
clk_o: out std_logic |
); |
end component; |
|
-- internal constants |
-- for simulation only / cannot be used when synthesizing |
constant CCSDS_TX_MANAGER_DEBUG: std_logic := '0'; |
-------------------------------- |
-- Clocks ratios computations -- |
-------------------------------- |
-- clk_dat |
---- clk_bit = clk_dat / parallelism * data_link_overhead_ratio |
------ clk_sym = clk_bit * data_bus_size / (2 * bits_per_symbol) |
-------- clk_sam = clk_sym * oversampling_ratio |
constant CCSDS_TX_MANAGER_SAMPLES_TO_SYMBOLS_RATIO: integer := CCSDS_TX_MANAGER_OVERSAMPLING_RATIO; |
constant CCSDS_TX_MANAGER_SAMPLES_TO_BITS_RATIO: integer := CCSDS_TX_MANAGER_MODULATION_TYPE*CCSDS_TX_MANAGER_SAMPLES_TO_SYMBOLS_RATIO*CCSDS_TX_MANAGER_DATA_BUS_SIZE/(CCSDS_TX_MANAGER_BITS_PER_SYMBOL*2); |
constant CCSDS_TX_MANAGER_SAMPLES_TO_DATA_RATIO: integer := CCSDS_TX_MANAGER_SAMPLES_TO_BITS_RATIO*CCSDS_TX_MANAGER_DATALINK_OVERHEAD_RATIO/CCSDS_TX_MANAGER_PARALLELISM_MAX_RATIO; |
|
-- interconnection signals |
signal wire_serdes_dat_par_o: std_logic_vector(CCSDS_TX_MANAGER_DATA_BUS_SIZE-1 downto 0); |
signal wire_serdes_dat_par_val_o: std_logic; |
signal wire_serdes_dat_ser_val_i: std_logic; |
signal wire_clk_dat: std_logic; |
signal wire_rst_clk: std_logic; |
|
begin |
-- presynthesis checks |
CHKMANAGERP0: if (CCSDS_TX_MANAGER_DEBUG = '1') generate |
process |
begin |
report "INFO: TX CLOCK FREQUENCY HAS TO BE " & integer'image(CCSDS_TX_MANAGER_SAMPLES_TO_DATA_RATIO) & " x WB DATA CLOCK" severity note; |
wait; |
end process; |
end generate CHKMANAGERP0; |
-- components instanciation and mapping |
clock_divider_bits_001: ccsds_rxtx_clock_divider |
generic map( |
CCSDS_RXTX_CLOCK_DIVIDER => CCSDS_TX_MANAGER_SAMPLES_TO_BITS_RATIO |
) |
port map( |
clk_i => clk_i, |
rst_i => wire_rst_clk, |
clk_o => clk_bit_o |
); |
clock_divider_dat_001: ccsds_rxtx_clock_divider |
generic map( |
CCSDS_RXTX_CLOCK_DIVIDER => CCSDS_TX_MANAGER_SAMPLES_TO_DATA_RATIO |
) |
port map( |
clk_i => clk_i, |
rst_i => wire_rst_clk, |
clk_o => wire_clk_dat |
); |
clock_divider_sam_001: ccsds_rxtx_clock_divider |
generic map( |
CCSDS_RXTX_CLOCK_DIVIDER => 1 |
) |
port map( |
clk_i => clk_i, |
rst_i => wire_rst_clk, |
clk_o => clk_sam_o |
); |
clock_divider_sym_001: ccsds_rxtx_clock_divider |
generic map( |
CCSDS_RXTX_CLOCK_DIVIDER => CCSDS_TX_MANAGER_SAMPLES_TO_SYMBOLS_RATIO |
) |
port map( |
clk_i => clk_i, |
rst_i => wire_rst_clk, |
clk_o => clk_sym_o |
); |
serdes_001: ccsds_rxtx_serdes |
generic map( |
CCSDS_RXTX_SERDES_DEPTH => CCSDS_TX_MANAGER_DATA_BUS_SIZE |
) |
port map( |
clk_i => wire_clk_dat, |
dat_par_i => (others => '0'), |
dat_par_val_i => '0', |
dat_ser_i => dat_ser_i, |
dat_ser_val_i => wire_serdes_dat_ser_val_i, |
rst_i => rst_i, |
dat_par_o => wire_serdes_dat_par_o, |
dat_par_val_o => wire_serdes_dat_par_val_o |
); |
|
ena_o <= ena_i; |
wire_rst_clk <= not(ena_i); |
clk_dat_o <= wire_clk_dat; |
--============================================================================= |
-- Begin of selectp |
-- Input selection |
--============================================================================= |
-- read: rst_i, ena_i, in_sel_i, dat_val_i |
-- write: dat_o, dat_val_o, wire_serdes_dat_ser_val_i |
-- r/w: |
SELECTP : process (wire_clk_dat, ena_i) |
-- variables instantiation |
begin |
-- on each clock rising edge |
if rising_edge(wire_clk_dat) and (ena_i = '1') then |
if (rst_i = '1') then |
dat_o <= (others => '0'); |
dat_val_o <= '0'; |
wire_serdes_dat_ser_val_i <= '0'; |
else |
if (in_sel_i = '1') then |
wire_serdes_dat_ser_val_i <= '1'; |
dat_o <= wire_serdes_dat_par_o; |
dat_val_o <= wire_serdes_dat_par_val_o; |
else |
wire_serdes_dat_ser_val_i <= '0'; |
dat_val_o <= dat_val_i; |
dat_o <= dat_par_i; |
end if; |
end if; |
end if; |
end process; |
end structure; |
/ccsds_tx_mapper_bits_symbols.vhd
0,0 → 1,118
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_tx_mapper_bits_symbols |
---- Version: 1.0.0 |
---- Description: |
---- Map input bits to complex I&Q symbols depending on modulation type |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/11/05: initial release |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary tx bits to symbols mapper inputs and outputs |
--============================================================================= |
entity ccsds_tx_mapper_bits_symbols is |
generic( |
constant CCSDS_TX_MAPPER_BITS_PER_SYMBOL: integer := 1; -- For QAM - 1 bit/symbol <=> QPSK/4-QAM - 2 bits/symbol <=> 16-QAM - 3 bits/symbol <=> 64-QAM - ... - N bits/symbol <=> 2^(N*2)-QAM |
constant CCSDS_TX_MAPPER_GRAY_CODER: std_logic := '1'; -- Gray coder activation |
constant CCSDS_TX_MAPPER_MODULATION_TYPE: integer := 1; -- 1=QPSK/QAM - 2=BPSK |
constant CCSDS_TX_MAPPER_DATA_BUS_SIZE: integer -- in bits |
); |
port( |
-- inputs |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_MAPPER_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
-- outputs |
sym_val_o: out std_logic; |
sym_i_o: out std_logic_vector(CCSDS_TX_MAPPER_BITS_PER_SYMBOL-1 downto 0); |
sym_q_o: out std_logic_vector(CCSDS_TX_MAPPER_BITS_PER_SYMBOL-1 downto 0) |
); |
end ccsds_tx_mapper_bits_symbols; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture rtl of ccsds_tx_mapper_bits_symbols is |
-- internal constants |
constant MAPPER_SYMBOL_NUMBER_PER_CHANNEL: integer := CCSDS_TX_MAPPER_DATA_BUS_SIZE*CCSDS_TX_MAPPER_MODULATION_TYPE/(2*CCSDS_TX_MAPPER_BITS_PER_SYMBOL); |
-- internal variable signals |
-- components instanciation and mapping |
begin |
-- presynthesis checks |
CHKMAPPERP0 : if (CCSDS_TX_MAPPER_DATA_BUS_SIZE mod (CCSDS_TX_MAPPER_BITS_PER_SYMBOL*2*CCSDS_TX_MAPPER_MODULATION_TYPE) /= 0) generate |
process |
begin |
report "ERROR: DATA BUS SIZE HAS TO BE A MULTIPLE OF 2*BITS PER SYMBOLS (EXCEPT FOR BPSK MODULATION)" severity failure; |
wait; |
end process; |
end generate CHKMAPPERP0; |
CHKMAPPERP1: if (CCSDS_TX_MAPPER_BITS_PER_SYMBOL /= 1) and (CCSDS_TX_MAPPER_MODULATION_TYPE = 2) generate |
process |
begin |
report "ERROR: BPSK MODULATION REQUIRES 1 BIT PER SYMBOL" severity failure; |
wait; |
end process; |
end generate CHKMAPPERP1; |
CHKMAPPERP2 : if (CCSDS_TX_MAPPER_MODULATION_TYPE /= 1) and (CCSDS_TX_MAPPER_MODULATION_TYPE /= 2) generate |
process |
begin |
report "ERROR: UNKNOWN MODULATION TYPE - 1=QPSK/QAM / 2=BPSK" severity failure; |
wait; |
end process; |
end generate CHKMAPPERP2; |
-- internal processing |
--============================================================================= |
-- Begin of mapperp |
-- Map bits to symbols |
--============================================================================= |
-- read: rst_i, dat_i, dat_val_i |
-- write: sym_i_o, sym_q_o, sym_val_o |
-- r/w: |
MAPPERP: process (clk_i) |
variable symbol_counter: integer range 1 to MAPPER_SYMBOL_NUMBER_PER_CHANNEL := MAPPER_SYMBOL_NUMBER_PER_CHANNEL; |
begin |
-- on each clock rising edge |
if rising_edge(clk_i) then |
-- reset signal received |
if (rst_i = '1') then |
sym_i_o <= (others => '0'); |
sym_q_o <= (others => '0'); |
symbol_counter := MAPPER_SYMBOL_NUMBER_PER_CHANNEL; |
sym_val_o <= '0'; |
else |
if (dat_val_i = '1') then |
sym_val_o <= '1'; |
-- BPSK mapping |
if (CCSDS_TX_MAPPER_BITS_PER_SYMBOL = 1) and (CCSDS_TX_MAPPER_MODULATION_TYPE = 2) then |
sym_q_o(0) <= '0'; |
sym_i_o(0) <= dat_i(symbol_counter-1); |
-- QPSK/QAM mapping |
else |
sym_i_o <= dat_i(symbol_counter*CCSDS_TX_MAPPER_BITS_PER_SYMBOL*2-1 downto symbol_counter*2*CCSDS_TX_MAPPER_BITS_PER_SYMBOL-CCSDS_TX_MAPPER_BITS_PER_SYMBOL); |
sym_q_o <= dat_i(symbol_counter*2*CCSDS_TX_MAPPER_BITS_PER_SYMBOL-CCSDS_TX_MAPPER_BITS_PER_SYMBOL-1 downto symbol_counter*2*CCSDS_TX_MAPPER_BITS_PER_SYMBOL-2*CCSDS_TX_MAPPER_BITS_PER_SYMBOL); |
end if; |
if (symbol_counter = 1) then |
symbol_counter := MAPPER_SYMBOL_NUMBER_PER_CHANNEL; |
else |
symbol_counter := symbol_counter - 1; |
end if; |
else |
sym_val_o <= '0'; |
end if; |
end if; |
end if; |
end process; |
end rtl; |
/ccsds_tx_mapper_symbols_samples.vhd
0,0 → 1,99
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_tx_mapper_symbols_samples |
---- Version: 1.0.0 |
---- Description: |
---- Map symbols to their sample value depending on quantization depth |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/11/18: initial release |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary tx bits to symbols mapper inputs and outputs |
--============================================================================= |
entity ccsds_tx_mapper_symbols_samples is |
generic( |
constant CCSDS_TX_MAPPER_TARGET_SNR: real; -- in dB |
constant CCSDS_TX_MAPPER_BITS_PER_SYMBOL: integer; -- in bits |
constant CCSDS_TX_MAPPER_QUANTIZATION_DEPTH: integer -- in bits |
); |
port( |
-- inputs |
clk_i: in std_logic; |
rst_i: in std_logic; |
sym_i: in std_logic_vector(CCSDS_TX_MAPPER_BITS_PER_SYMBOL-1 downto 0); |
sym_val_i: in std_logic; |
-- outputs |
sam_val_o: out std_logic; |
sam_o: out std_logic_vector(CCSDS_TX_MAPPER_QUANTIZATION_DEPTH-1 downto 0) |
); |
end ccsds_tx_mapper_symbols_samples; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture rtl of ccsds_tx_mapper_symbols_samples is |
-- internal constants |
constant QUANTIZATION_SNR: real := 6.02*real(CCSDS_TX_MAPPER_QUANTIZATION_DEPTH); |
constant REQUIRED_SNR: real := real(2 + 2*CCSDS_TX_MAPPER_BITS_PER_SYMBOL) + CCSDS_TX_MAPPER_TARGET_SNR; |
constant SYMBOL_STEP: real := 2.0**(CCSDS_TX_MAPPER_QUANTIZATION_DEPTH) / real(CCSDS_TX_MAPPER_BITS_PER_SYMBOL+1); |
-- internal variable signals |
type samples_array is array(2**(CCSDS_TX_MAPPER_BITS_PER_SYMBOL)-1 downto 0) of std_logic_vector(CCSDS_TX_MAPPER_QUANTIZATION_DEPTH-1 downto 0); |
signal symbols_values: samples_array; |
-- components instanciation and mapping |
begin |
SYMBOLS_VALUES_GENERATOR: for symbol_counter in 0 to 2**(CCSDS_TX_MAPPER_BITS_PER_SYMBOL-1)-1 generate |
symbols_values(2**(CCSDS_TX_MAPPER_BITS_PER_SYMBOL-1)+symbol_counter) <= std_logic_vector(to_signed(integer(2.0**(CCSDS_TX_MAPPER_QUANTIZATION_DEPTH-1) - 1.0 - real(symbol_counter) * SYMBOL_STEP),CCSDS_TX_MAPPER_QUANTIZATION_DEPTH)); |
symbols_values(2**(CCSDS_TX_MAPPER_BITS_PER_SYMBOL-1)-symbol_counter-1) <= std_logic_vector(to_signed(integer(-(2.0**(CCSDS_TX_MAPPER_QUANTIZATION_DEPTH-1)) + 1.0 + real(symbol_counter) * SYMBOL_STEP),CCSDS_TX_MAPPER_QUANTIZATION_DEPTH)); |
end generate SYMBOLS_VALUES_GENERATOR; |
-- presynthesis checks |
-- Check SNR level requested is respected |
-- Signal SNR > crest factor modulated signal + SNR requested from configuration |
-- QAMCrestFactor, dB # 2 + 2 * NumberOfBitsPerSymbol |
-- QuantizedSignal SNR, dB # 6.02 * QuantizationDepth |
CHKMAPPERP0 : if (QUANTIZATION_SNR < REQUIRED_SNR) generate |
process |
begin |
report "ERROR: INCREASE QUANTIZATION DEPTH - QUANTIZATION SNR = " & real'image(QUANTIZATION_SNR) & " dB - REQUIRED SNR = " & real'image(REQUIRED_SNR) severity failure; |
wait; |
end process; |
end generate CHKMAPPERP0; |
-- internal processing |
--============================================================================= |
-- Begin of mapperp |
-- Map symbols to samples |
--============================================================================= |
-- read: rst_i, sym_i, sym_val_i |
-- write: sam_val_o, sam_o |
-- r/w: |
MAPPERP: process (clk_i) |
begin |
-- on each clock rising edge |
if rising_edge(clk_i) then |
-- reset signal received |
if (rst_i = '1') then |
sam_o <= (others => '0'); |
sam_val_o <= '0'; |
else |
if (sym_val_i = '1') then |
sam_o <= symbols_values(to_integer(unsigned(sym_i))); |
sam_val_o <= '1'; |
else |
sam_val_o <= '0'; |
end if; |
end if; |
end if; |
end process; |
end rtl; |
/ccsds_tx_physical_layer.vhd
0,0 → 1,119
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_tx_physical_layer |
---- Version: 1.0.0 |
---- Description: |
---- Implementation of standard CCSDS 401.0-B |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2015/11/17: initial release |
------------------------------- |
--TODO: Gray coder |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
-- unitary tx physical layer |
entity ccsds_tx_physical_layer is |
generic ( |
constant CCSDS_TX_PHYSICAL_BITS_PER_SYMBOL: integer; |
constant CCSDS_TX_PHYSICAL_MODULATION_TYPE: integer; |
constant CCSDS_TX_PHYSICAL_DATA_BUS_SIZE: integer; |
constant CCSDS_TX_PHYSICAL_OVERSAMPLING_RATIO: integer; |
constant CCSDS_TX_PHYSICAL_SIG_QUANT_DEPTH : integer |
); |
port( |
-- inputs |
clk_sam_i: in std_logic; |
clk_sym_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_PHYSICAL_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
-- outputs |
sam_i_o: out std_logic_vector(CCSDS_TX_PHYSICAL_SIG_QUANT_DEPTH-1 downto 0); |
sam_q_o: out std_logic_vector(CCSDS_TX_PHYSICAL_SIG_QUANT_DEPTH-1 downto 0) |
); |
end ccsds_tx_physical_layer; |
|
-- internal processing |
architecture structure of ccsds_tx_physical_layer is |
component ccsds_tx_mapper_bits_symbols is |
generic( |
CCSDS_TX_MAPPER_DATA_BUS_SIZE: integer; |
CCSDS_TX_MAPPER_MODULATION_TYPE: integer; |
CCSDS_TX_MAPPER_BITS_PER_SYMBOL: integer |
); |
port( |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_MAPPER_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
sym_val_o: out std_logic; |
sym_i_o: out std_logic_vector(CCSDS_TX_MAPPER_BITS_PER_SYMBOL-1 downto 0); |
sym_q_o: out std_logic_vector(CCSDS_TX_MAPPER_BITS_PER_SYMBOL-1 downto 0) |
); |
end component; |
component ccsds_tx_filter is |
generic( |
CCSDS_TX_FILTER_OVERSAMPLING_RATIO: integer; |
CCSDS_TX_FILTER_SIG_QUANT_DEPTH: integer; |
CCSDS_TX_FILTER_MODULATION_TYPE: integer; |
CCSDS_TX_FILTER_BITS_PER_SYMBOL: integer |
); |
port( |
clk_i: in std_logic; |
sym_val_i: in std_logic; |
sym_i_i: in std_logic_vector(CCSDS_TX_FILTER_BITS_PER_SYMBOL-1 downto 0); |
sym_q_i: in std_logic_vector(CCSDS_TX_FILTER_BITS_PER_SYMBOL-1 downto 0); |
rst_i: in std_logic; |
sam_i_o: out std_logic_vector(CCSDS_TX_FILTER_SIG_QUANT_DEPTH-1 downto 0); |
sam_q_o: out std_logic_vector(CCSDS_TX_FILTER_SIG_QUANT_DEPTH-1 downto 0); |
sam_val_o: out std_logic |
); |
end component; |
|
signal wire_sym_i: std_logic_vector(CCSDS_TX_PHYSICAL_BITS_PER_SYMBOL-1 downto 0); |
signal wire_sym_q: std_logic_vector(CCSDS_TX_PHYSICAL_BITS_PER_SYMBOL-1 downto 0); |
signal wire_sym_val: std_logic; |
|
begin |
tx_mapper_bits_symbols_0: ccsds_tx_mapper_bits_symbols |
generic map( |
CCSDS_TX_MAPPER_BITS_PER_SYMBOL => CCSDS_TX_PHYSICAL_BITS_PER_SYMBOL, |
CCSDS_TX_MAPPER_MODULATION_TYPE => CCSDS_TX_PHYSICAL_MODULATION_TYPE, |
CCSDS_TX_MAPPER_DATA_BUS_SIZE => CCSDS_TX_PHYSICAL_DATA_BUS_SIZE |
) |
port map( |
clk_i => clk_sym_i, |
dat_i => dat_i, |
dat_val_i => dat_val_i, |
rst_i => rst_i, |
sym_i_o => wire_sym_i, |
sym_q_o => wire_sym_q, |
sym_val_o => wire_sym_val |
); |
tx_filter_0: ccsds_tx_filter |
generic map( |
CCSDS_TX_FILTER_OVERSAMPLING_RATIO => CCSDS_TX_PHYSICAL_OVERSAMPLING_RATIO, |
CCSDS_TX_FILTER_MODULATION_TYPE => CCSDS_TX_PHYSICAL_MODULATION_TYPE, |
CCSDS_TX_FILTER_SIG_QUANT_DEPTH => CCSDS_TX_PHYSICAL_SIG_QUANT_DEPTH, |
CCSDS_TX_FILTER_BITS_PER_SYMBOL => CCSDS_TX_PHYSICAL_BITS_PER_SYMBOL |
) |
port map( |
clk_i => clk_sam_i, |
sym_i_i => wire_sym_i, |
sym_q_i => wire_sym_q, |
sym_val_i => wire_sym_val, |
rst_i => rst_i, |
-- sam_val_o => , |
sam_i_o => sam_i_o, |
sam_q_o => sam_q_o |
); |
end structure; |
/ccsds_tx_randomizer.vhd
0,0 → 1,106
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_tx_randomizer |
---- Version: 1.0.0 |
---- Description: |
---- Randomize input data with LFSR output sequence |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/11/05: initial release |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary tx randomizer inputs and outputs |
--============================================================================= |
entity ccsds_tx_randomizer is |
generic( |
constant CCSDS_TX_RANDOMIZER_DATA_BUS_SIZE: integer -- in bits |
); |
port( |
-- inputs |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_RANDOMIZER_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
-- outputs |
dat_o: out std_logic_vector(CCSDS_TX_RANDOMIZER_DATA_BUS_SIZE-1 downto 0); |
dat_val_o: out std_logic |
); |
end ccsds_tx_randomizer; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture structure of ccsds_tx_randomizer is |
component ccsds_rxtx_lfsr is |
generic( |
CCSDS_RXTX_LFSR_DATA_BUS_SIZE: integer |
); |
port( |
clk_i: in std_logic; |
rst_i: in std_logic; |
dat_o: out std_logic_vector(CCSDS_RXTX_LFSR_DATA_BUS_SIZE-1 downto 0); |
dat_val_o: out std_logic |
); |
end component; |
-- internal constants |
-- internal variable signals |
signal randomizer_sequence: std_logic_vector(CCSDS_TX_RANDOMIZER_DATA_BUS_SIZE-1 downto 0); |
signal wire_lfsr_valid: std_logic; |
-- components instanciation and mapping |
begin |
tx_randomizer_lfsr: ccsds_rxtx_lfsr |
generic map( |
CCSDS_RXTX_LFSR_DATA_BUS_SIZE => CCSDS_TX_RANDOMIZER_DATA_BUS_SIZE |
) |
port map( |
clk_i => clk_i, |
rst_i => rst_i, |
dat_val_o => wire_lfsr_valid, |
dat_o => randomizer_sequence |
); |
|
-- presynthesis checks |
-- internal processing |
--============================================================================= |
-- Begin of randp |
-- Randomize data using LFSR register |
--============================================================================= |
-- read: rst_i, dat_val_i, dat_i, randomizer_sequence, wire_lfsr_valid |
-- write: dat_o, dat_val_o |
-- r/w: |
RANDP: process (clk_i) |
variable data_randomized: std_logic := '0'; |
begin |
-- on each clock rising edge |
if rising_edge(clk_i) then |
-- reset signal received |
if (rst_i = '1') then |
dat_o <= (others => '0'); |
data_randomized := '0'; |
dat_val_o <= '0'; |
else |
if (dat_val_i = '1') and (wire_lfsr_valid = '1') then |
dat_val_o <= '1'; |
dat_o <= dat_i xor randomizer_sequence; |
data_randomized := '1'; |
else |
dat_val_o <= '0'; |
if (data_randomized = '0') then |
dat_o <= (others => '0'); |
end if; |
end if; |
end if; |
end if; |
end process; |
end structure; |
/ccsds_tx_synchronizer.vhd
0,0 → 1,93
------------------------------- |
---- Project: EurySPACE CCSDS RX/TX with wishbone interface |
---- Design Name: ccsds_tx_synchronizer |
---- Version: 1.0.0 |
---- Description: |
---- Add an Attached Synchronization Marker to an input frame |
------------------------------- |
---- Author(s): |
---- Guillaume REMBERT |
------------------------------- |
---- Licence: |
---- MIT |
------------------------------- |
---- Changes list: |
---- 2016/11/05: initial release |
------------------------------- |
|
-- libraries used |
library ieee; |
use ieee.std_logic_1164.all; |
|
--============================================================================= |
-- Entity declaration for ccsds_tx / unitary tx synchronizer inputs and outputs |
--============================================================================= |
entity ccsds_tx_synchronizer is |
generic( |
constant CCSDS_TX_ASM_LENGTH: integer := 4; -- Attached Synchronization Marker length / in Bytes |
constant CCSDS_TX_ASM_PATTERN: std_logic_vector := "00011010110011111111110000011101"; -- ASM Pattern used |
constant CCSDS_TX_ASM_DATA_BUS_SIZE: integer -- in bits |
); |
port( |
-- inputs |
clk_i: in std_logic; |
dat_i: in std_logic_vector(CCSDS_TX_ASM_DATA_BUS_SIZE-1 downto 0); |
dat_val_i: in std_logic; |
rst_i: in std_logic; |
-- outputs |
dat_o: out std_logic_vector(CCSDS_TX_ASM_DATA_BUS_SIZE+CCSDS_TX_ASM_LENGTH*8-1 downto 0); |
dat_val_o: out std_logic |
); |
end ccsds_tx_synchronizer; |
|
--============================================================================= |
-- architecture declaration / internal components and connections |
--============================================================================= |
architecture structure of ccsds_tx_synchronizer is |
|
-- internal constants |
-- internal variable signals |
-- components instanciation and mapping |
begin |
-- presynthesis checks |
CHKSYNCHRONIZERP0 : if ((CCSDS_TX_ASM_LENGTH*8) /= CCSDS_TX_ASM_PATTERN'length) generate |
process |
begin |
report "ERROR: SYNCHRONIZER ASM LENGTH IS DIFFERENT FROM PATTERN SIZE" severity failure; |
wait; |
end process; |
end generate CHKSYNCHRONIZERP0; |
-- internal processing |
--============================================================================= |
-- Begin of asmp |
-- Apped ASM sequence to frame |
--============================================================================= |
-- read: rst_i, dat_val_i, dat_i |
-- write: dat_o, dat_val_o |
-- r/w: |
ASMP: process (clk_i) |
variable data_synchronized: std_logic := '0'; |
begin |
-- on each clock rising edge |
if rising_edge(clk_i) then |
-- reset signal received |
if (rst_i = '1') then |
dat_o <= (others => '0'); |
data_synchronized := '0'; |
dat_val_o <= '0'; |
else |
if (dat_val_i = '1') then |
dat_o(CCSDS_TX_ASM_DATA_BUS_SIZE+CCSDS_TX_ASM_LENGTH*8-1 downto CCSDS_TX_ASM_DATA_BUS_SIZE) <= CCSDS_TX_ASM_PATTERN; |
dat_o(CCSDS_TX_ASM_DATA_BUS_SIZE-1 downto 0) <= dat_i; |
data_synchronized := '1'; |
dat_val_o <= '1'; |
else |
dat_val_o <= '0'; |
if (data_synchronized = '0') then |
dat_o <= (others => '0'); |
end if; |
end if; |
end if; |
end if; |
end process; |
end structure; |