|
|
----------------------------------------------------------------------------------
|
|
|
-- Company:
|
|
|
-- Engineer:
|
|
|
--
|
|
|
-- Create Date: 11:35:58 02/20/2017
|
|
|
-- Design Name:
|
|
|
-- Module Name: joiner_samp - Behavioral
|
|
|
-- Project Name:
|
|
|
-- Target Devices:
|
|
|
-- Tool versions:
|
|
|
-- Description:
|
|
|
--
|
|
|
-- Dependencies:
|
|
|
--
|
|
|
-- Revision:
|
|
|
-- Revision 0.01 - File Created
|
|
|
-- Additional Comments:
|
|
|
--
|
|
|
----------------------------------------------------------------------------------
|
|
|
library IEEE;
|
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
|
|
|
|
|
-- Uncomment the following library declaration if using
|
|
|
-- arithmetic functions with Signed or Unsigned values
|
|
|
use IEEE.NUMERIC_STD.ALL;
|
|
|
|
|
|
-- Uncomment the following library declaration if instantiating
|
|
|
-- any Xilinx primitives in this code.
|
|
|
--library UNISIM;
|
|
|
--use UNISIM.VComponents.all;
|
|
|
|
|
|
entity joiner_samp is
|
|
|
GENERIC(
|
|
|
DBIT_SZ: INTEGER :=3;
|
|
|
BITS_COUNT_SZ: INTEGER :=3;
|
|
|
RESUL_NP_SZ: INTEGER :=40;
|
|
|
SAMPLE_SZ: INTEGER :=24;
|
|
|
SAMPLE_COUNT_SZ: INTEGER := 12;
|
|
|
HEADER_NIB_SZ: INTEGER := 4;
|
|
|
DATA_HEADER_NIB_SZ: INTEGER := 4;
|
|
|
CH_COUNT_SZ: INTEGER :=4
|
|
|
);
|
|
|
|
|
|
PORT(
|
|
|
|
|
|
--Channel number
|
|
|
chn_id_acq: IN STD_LOGIC_VECTOR((CH_COUNT_SZ-1) downto 0);
|
|
|
|
|
|
--Reset del sistema
|
|
|
rst_bar: IN STD_LOGIC;
|
|
|
|
|
|
--Reloj principal
|
|
|
clk_main: IN STD_LOGIC; --Reloj externo de por lo menos 32MHz proveniente del m�dulo de sincronizaci�n
|
|
|
|
|
|
--Senhales con el microcontrolador
|
|
|
clk_acq: IN STD_LOGIC; --Senhal de "reloj" proveniente del XMEGA por canal del m�dulo de adquisici�n
|
|
|
chn_bits_acq: IN STD_LOGIC_VECTOR((DBIT_SZ-1) downto 0); --Nibble de datos provenientes del XMEGA por canal del m�dulo de adquisici�n
|
|
|
|
|
|
--Data req
|
|
|
dat_req_ch: IN STD_LOGIC;
|
|
|
|
|
|
--Senhales hacia el sistema
|
|
|
resul_samp: OUT STD_LOGIC_VECTOR((RESUL_NP_SZ-1) downto 0); --Salida al espacio de memoria para almacenar datos crudos
|
|
|
rdy_samp: OUT STD_LOGIC; --Senhal para indicar que el dato fue obtenido satisfactoriamente y esta listo para ser almacenado en memoria
|
|
|
ack_in: IN STD_LOGIC --Senhal para indicar que el dato presentado fue leido o no
|
|
|
|
|
|
);
|
|
|
end joiner_samp;
|
|
|
|
|
|
architecture Behavioral of joiner_samp is
|
|
|
|
|
|
--Registros para sincronizacion
|
|
|
SIGNAL clk_acq_r : std_logic_vector (2 downto 0) :=(OTHERS=>'1');
|
|
|
SIGNAL chn_bits_acq_bit0 : std_logic_vector (1 downto 0) :=(OTHERS=>'0');
|
|
|
SIGNAL chn_bits_acq_bit1 : std_logic_vector (1 downto 0) :=(OTHERS=>'0');
|
|
|
SIGNAL chn_bits_acq_bit2 : std_logic_vector (1 downto 0) :=(OTHERS=>'0');
|
|
|
|
|
|
--Senhales para deteccion de flancos
|
|
|
SIGNAL clk_acq_rise : std_logic :='0';
|
|
|
|
|
|
--Senhal Interna de dato completo
|
|
|
SIGNAL rdy_mem_aux: std_logic :='0';
|
|
|
|
|
|
--Constantes asociadas al contador de nibbles
|
|
|
SIGNAL dbits_counter : std_logic_vector ((BITS_COUNT_SZ-1) downto 0) :=(OTHERS=>'0');
|
|
|
CONSTANT TOP_COUNT: std_logic_vector((BITS_COUNT_SZ-1) downto 0) :="111";
|
|
|
CONSTANT BASE_COUNT: std_logic_vector((BITS_COUNT_SZ-1) downto 0) :=(OTHERS=>'0');
|
|
|
|
|
|
--Senhales para almacenar resultado a siguiente etapa
|
|
|
SIGNAL resul_mem_internal: std_logic_vector((SAMPLE_SZ-1) downto 0) :=(OTHERS=>'0');
|
|
|
SIGNAL resul_mem_internal_aux: std_logic_vector((RESUL_NP_SZ-1) downto 0) :=(OTHERS=>'0');
|
|
|
|
|
|
--Estados de la maquina de presentacion de datos a la RAM y RAM Controller
|
|
|
TYPE data_states IS ( idle,
|
|
|
data_pres, data_proc
|
|
|
);
|
|
|
SIGNAL data_cur_state: data_states := idle;
|
|
|
SIGNAL data_next_state: data_states := idle;
|
|
|
|
|
|
--Estados de la maquina de construccion de paquete
|
|
|
TYPE pack_states IS ( idle,
|
|
|
building
|
|
|
);
|
|
|
SIGNAL pack_cur_state : pack_states := idle;
|
|
|
SIGNAL pack_next_state : pack_states := idle;
|
|
|
|
|
|
SIGNAL nibble_aux: STD_LOGIC_VECTOR((DBIT_SZ-1) downto 0) := (OTHERS => '0');
|
|
|
SIGNAL samp_count: STD_LOGIC_VECTOR((SAMPLE_COUNT_SZ-1) downto 0) := (OTHERS => '0');
|
|
|
CONSTANT TOP_SAMPLES_COUNT: std_logic_vector((SAMPLE_COUNT_SZ-1) downto 0) := "001111101000";
|
|
|
begin
|
|
|
|
|
|
--Etapa de sincronizacion
|
|
|
sync_data: PROCESS(clk_main)
|
|
|
BEGIN
|
|
|
IF(rising_edge(clk_main)) THEN
|
|
|
IF(rst_bar = '0') THEN
|
|
|
chn_bits_acq_bit0 <= (OTHERS=>'0');
|
|
|
chn_bits_acq_bit1 <= (OTHERS=>'0');
|
|
|
chn_bits_acq_bit2 <= (OTHERS=>'0');
|
|
|
ELSE
|
|
|
chn_bits_acq_bit0 <= chn_bits_acq_bit0(0) & chn_bits_acq(0);
|
|
|
chn_bits_acq_bit1 <= chn_bits_acq_bit1(0) & chn_bits_acq(1);
|
|
|
chn_bits_acq_bit2 <= chn_bits_acq_bit2(0) & chn_bits_acq(2);
|
|
|
END IF;
|
|
|
END IF;
|
|
|
END PROCESS;
|
|
|
|
|
|
nibble_aux <= chn_bits_acq_bit2(1) &
|
|
|
chn_bits_acq_bit1(1) & chn_bits_acq_bit0(1);
|
|
|
|
|
|
--Etapa de deteccion de flancos
|
|
|
edge_det: PROCESS(clk_main)
|
|
|
BEGIN
|
|
|
IF(rising_edge(clk_main)) THEN
|
|
|
IF(rst_bar = '0') THEN
|
|
|
clk_acq_r <=(OTHERS =>'1');
|
|
|
clk_acq_rise <= '0';
|
|
|
|
|
|
ELSE
|
|
|
clk_acq_r <= clk_acq_r(1 downto 0) & clk_acq;
|
|
|
IF (clk_acq_r(2 downto 1) = "01") THEN
|
|
|
clk_acq_rise <= '1';
|
|
|
ELSE
|
|
|
clk_acq_rise <= '0';
|
|
|
END IF;
|
|
|
|
|
|
END IF;
|
|
|
END IF;
|
|
|
END PROCESS;
|
|
|
|
|
|
--Etapa de deteccion de cabecera y almacenamiento
|
|
|
cambio_estados: PROCESS(clk_main)
|
|
|
BEGIN
|
|
|
IF (rising_edge(clk_main)) THEN
|
|
|
IF(rst_bar = '0') THEN
|
|
|
pack_cur_state <= idle;
|
|
|
ELSE
|
|
|
pack_cur_state <= pack_next_state;
|
|
|
END IF;
|
|
|
END IF;
|
|
|
END PROCESS;
|
|
|
|
|
|
salidas_estados: PROCESS(pack_cur_state, dbits_counter,clk_acq_rise,dat_req_ch)
|
|
|
BEGIN
|
|
|
CASE pack_cur_state IS
|
|
|
WHEN idle =>
|
|
|
IF(dat_req_ch = '1') THEN
|
|
|
pack_next_state <= building;
|
|
|
ELSE
|
|
|
pack_next_state <= idle;
|
|
|
END IF;
|
|
|
WHEN building =>
|
|
|
IF(clk_acq_rise = '1') THEN
|
|
|
IF (dbits_counter = TOP_COUNT) THEN
|
|
|
pack_next_state <= idle;
|
|
|
ELSE
|
|
|
pack_next_state <= building;
|
|
|
END IF;
|
|
|
ELSE
|
|
|
pack_next_state <= building;
|
|
|
END IF;
|
|
|
|
|
|
WHEN OTHERS =>
|
|
|
pack_next_state <= idle;
|
|
|
|
|
|
END CASE;
|
|
|
END PROCESS;
|
|
|
|
|
|
save_bits: PROCESS(clk_main)
|
|
|
BEGIN
|
|
|
IF(rising_edge(clk_main)) THEN
|
|
|
IF (rst_bar = '0') THEN
|
|
|
dbits_counter <=(OTHERS => '0') ;
|
|
|
resul_mem_internal <=(OTHERS => '0') ;
|
|
|
ELSE
|
|
|
IF (pack_cur_state = building) THEN
|
|
|
|
|
|
IF(dat_req_ch = '1') THEN
|
|
|
dbits_counter <=(OTHERS => '0') ;
|
|
|
ELSIF(clk_acq_rise = '1') THEN
|
|
|
dbits_counter <=std_logic_vector(unsigned(dbits_counter)+1);
|
|
|
CASE dbits_counter IS
|
|
|
WHEN "000" =>
|
|
|
resul_mem_internal(23 downto 21) <= nibble_aux;
|
|
|
WHEN "001" =>
|
|
|
resul_mem_internal(20 downto 18) <= nibble_aux;
|
|
|
WHEN "010" =>
|
|
|
resul_mem_internal(17 downto 15) <= nibble_aux;
|
|
|
WHEN "011" =>
|
|
|
resul_mem_internal(14 downto 12) <= nibble_aux;
|
|
|
WHEN "100" =>
|
|
|
resul_mem_internal(11 downto 9) <= nibble_aux;
|
|
|
WHEN "101" =>
|
|
|
resul_mem_internal(8 downto 6) <= nibble_aux;
|
|
|
WHEN "110"=>
|
|
|
resul_mem_internal(5 downto 3) <= nibble_aux;
|
|
|
WHEN "111"=>
|
|
|
resul_mem_internal(2 downto 0) <= nibble_aux;
|
|
|
dbits_counter <=(OTHERS => '0');
|
|
|
WHEN OTHERS =>
|
|
|
dbits_counter <=(OTHERS => '0');
|
|
|
END CASE;
|
|
|
END IF;
|
|
|
END IF;
|
|
|
END IF;
|
|
|
END IF;
|
|
|
END PROCESS;
|
|
|
|
|
|
resul_mem_internal_aux(39 downto 36) <= chn_id_acq;
|
|
|
|
|
|
guardar_dato: PROCESS(clk_main)
|
|
|
BEGIN
|
|
|
IF (rising_edge(clk_main)) THEN
|
|
|
IF(data_cur_state = idle) THEN
|
|
|
IF(rdy_mem_aux = '1') THEN
|
|
|
resul_mem_internal_aux((RESUL_NP_SZ-5)downto 0) <= --chn_id_acq &
|
|
|
samp_count &
|
|
|
resul_mem_internal;
|
|
|
END IF;
|
|
|
END IF;
|
|
|
END IF;
|
|
|
END PROCESS;
|
|
|
|
|
|
conteo_muestra: PROCESS(clk_main)
|
|
|
BEGIN
|
|
|
IF (rising_edge(clk_main)) THEN
|
|
|
IF(dat_req_ch = '1') THEN
|
|
|
IF(samp_count = TOP_SAMPLES_COUNT) THEN
|
|
|
samp_count <= (OTHERS=>'0');
|
|
|
ELSE
|
|
|
samp_count <= std_logic_vector(unsigned(samp_count)+1) ;
|
|
|
END IF;
|
|
|
END IF;
|
|
|
END IF;
|
|
|
END PROCESS;
|
|
|
|
|
|
output_rdy_mem: PROCESS(clk_main)
|
|
|
BEGIN
|
|
|
IF(rising_edge(clk_main)) THEN
|
|
|
IF (rst_bar = '0') THEN
|
|
|
rdy_mem_aux <= '0';
|
|
|
ELSE
|
|
|
IF((dbits_counter = TOP_COUNT)) THEN
|
|
|
IF((clk_acq_rise = '1')) THEN
|
|
|
rdy_mem_aux <= '1';
|
|
|
END IF;
|
|
|
ELSE
|
|
|
rdy_mem_aux <= '0';
|
|
|
END IF;
|
|
|
END IF;
|
|
|
END IF;
|
|
|
END PROCESS;
|
|
|
|
|
|
cambio_estados_data: PROCESS(clk_main)
|
|
|
BEGIN
|
|
|
IF (rising_edge(clk_main)) THEN
|
|
|
IF(rst_bar = '0') THEN
|
|
|
data_cur_state <= idle;
|
|
|
ELSE
|
|
|
data_cur_state <= data_next_state;
|
|
|
END IF;
|
|
|
END IF;
|
|
|
END PROCESS;
|
|
|
|
|
|
salidas_estados_data: PROCESS(resul_mem_internal_aux,data_cur_state,ack_in,rdy_mem_aux)
|
|
|
BEGIN
|
|
|
CASE data_cur_state IS
|
|
|
WHEN idle =>
|
|
|
rdy_samp <= '0';
|
|
|
resul_samp <= (OTHERS => '0');
|
|
|
IF (rdy_mem_aux = '1') THEN
|
|
|
data_next_state <= data_pres;
|
|
|
ELSE
|
|
|
data_next_state <= idle;
|
|
|
END IF;
|
|
|
|
|
|
WHEN data_pres =>
|
|
|
rdy_samp <= '1';
|
|
|
resul_samp <= resul_mem_internal_aux;
|
|
|
IF (ack_in = '1') THEN
|
|
|
data_next_state <= data_proc;
|
|
|
ELSE
|
|
|
data_next_state <= data_pres;
|
|
|
END IF;
|
|
|
|
|
|
WHEN data_proc =>
|
|
|
rdy_samp <= '1';
|
|
|
resul_samp <= resul_mem_internal_aux;
|
|
|
IF (ack_in = '0') THEN --Si ya est� ocupado con el dato antes presentado entonces ya puedo ir pidiendo otro dato
|
|
|
data_next_state <= idle;
|
|
|
ELSE
|
|
|
data_next_state <= data_proc;
|
|
|
END IF;
|
|
|
|
|
|
WHEN OTHERS =>
|
|
|
rdy_samp <= '0';
|
|
|
resul_samp <= (OTHERS => '0');
|
|
|
data_next_state <= idle;
|
|
|
|
|
|
END CASE;
|
|
|
END PROCESS;
|
|
|
|
|
|
end Behavioral;
|
|
|
|
|
|
|