Commit 2d643acd authored by Guillaume REMBERT's avatar Guillaume REMBERT

Convolutional coder initial release + predefined types package creation

parent 7f5f0fc5
......@@ -16,12 +16,13 @@ files =
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_convolutional.vhd
ccsds_tx_coder_differential.vhd
ccsds_tx_datalink_layer.vhd
ccsds_tx_filter.vhd
......
This diff is collapsed.
......@@ -15,6 +15,7 @@
---- 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
......@@ -22,10 +23,12 @@ 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;
......@@ -42,6 +45,16 @@ package body ccsds_rxtx_functions is
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);
......
-------------------------------
---- 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;
---- 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;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment