OpenCores
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
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/trunk/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;
/trunk/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;
/trunk/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
--=============================================================================
/trunk/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
/trunk/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
--=============================================================================
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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
--=============================================================================
/trunk/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;
/trunk/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
--=============================================================================
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;
/trunk/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;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.