OpenCores
URL https://opencores.org/ocsvn/lateq/lateq/trunk

Subversion Repositories lateq

[/] [lateq/] [trunk/] [hdl_various_types/] [src/] [ex1_proc.vhd] - Rev 4

Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
-- Title      : Example 1 - data processor
-- Project    : 
-------------------------------------------------------------------------------
-- File       : ex1_proc.vhd
-- Author     : Wojciech M. Zabolotny  <wzab01@gmail.com>
-- Company    : 
-- License    : BSD
-- Created    : 2015-09-07
-- Last update: 2015-09-24
-- Platform   : 
-- Standard   : VHDL'93/02
-------------------------------------------------------------------------------
-- Description: This file implements the data processor which demonstrates
--              the methodology of automatic latency balancing in VHDL
--              implemented pipelined blocks
-------------------------------------------------------------------------------
-- Copyright (c) 2015 
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2015-09-07  1.0      wzab    Created
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
library work;
use work.lateq_pkg.all;
use work.ex1_pkg.all;
use work.ex1_trees_pkg.all;
 
entity ex1_proc is
 
  port (
    din           : in  T_INPUT_DATA;  -- data from the detector
    position      : out T_POS_INT;      -- integral part of the hit position
    wgt_charge : out T_CALC_DATA;     -- fractional part of the hit position
    charge        : out T_CALC_DATA;       -- hit charge
    clk           : in  std_logic;      -- system clock
    rst_p         : in  std_logic);     -- reset
 
end entity ex1_proc;
 
architecture beh of ex1_proc is
 
  -- Input signals in internal form (with time markers)
  signal din_int, din_int_a : T_INPUT_DATA_MRK := C_INPUT_DATA_MRK_INIT;
  -- pragma translate_off
  -- Time marker
  signal s_lateq_mrk : T_LATEQ_MRK := C_LATEQ_MRK_INIT;
  -- pragma translate_on
  -- Output signal from the max_finder
  signal dout_max : T_SINGLE_DATA_WITH_POS := C_SINGLE_DATA_WITH_POS_INIT;
  -- Selected data surrounding the maximum of the signal
  signal sel_data : T_SEL_DATA := C_SEL_DATA_INIT;
  -- Selected data with longer data word
  signal s_sel_data, wgt_sel_data : T_CALC_SEL_DATA := C_CALC_SEL_DATA_INIT;
  -- Sum of charge and weighted sum of charge
  signal chrg_sum, wgt_chrg_sum : T_CALC_DATA_MRK := C_CALC_DATA_MRK_INIT;
  -- Sum of charge and weighted sum of charge after synchronizer  
  signal chrg_sum_b, wgt_chrg_sum_b : T_CALC_DATA_MRK := C_CALC_DATA_MRK_INIT;
  -- Position of maximum - delayed signals after other blocks or sycnhronizers
  signal s_position_a, s_position_b, s_position_c : T_POS_INT_MRK := C_POS_INT_MRK_INIT;
 
begin  -- architecture beh
 
  -- Process which generates the time markers for the input data
  -- It is unclear. Should it be here, or in the testbench?
 
  pgm1: process (clk) is
  begin  -- process pgm1
    if clk'event and clk = '1' then     -- rising clock edge
      if rst_p = '1' then               -- synchronous reset (active low)
        -- pragma translate_off
        s_lateq_mrk <= C_LATEQ_MRK_INIT;
        -- pragma translate_on
        din_int <= C_INPUT_DATA_MRK_INIT;
      else
        din_int.data_vec <= din;
        -- pragma translate_off
        din_int.lateq_mrk <= s_lateq_mrk;
        s_lateq_mrk <= lateq_mrk_incr(s_lateq_mrk);
        -- pragma translate_on        
      end if;
    end if;
  end process pgm1;
 
  -- The first block is the maximum finder.
  max_finder_1: entity work.max_finder
    generic map (
      N_OF_ALL_INS => C_N_CHANNELS
      )
    port map (
      dins  => din_int,
      dout  => dout_max,
      clk   => clk,
      rst_p => rst_p);
  -- Now we should correct delays between the input data
  -- and output of the maximum finder
  -- So we have our delay adjustment block with two channels
  --
  s_position_a.position <= dout_max.position;
  -- pragma translate_off
  s_position_a.lateq_mrk <= dout_max.lateq_mrk;
  -- pragma translate_on
 
  ex1_eq_mf_1: entity work.ex1_eq_mf
    generic map (
      LEQ_ID => "LCEQ1")
    port map (
      in0   => din_int,
      out0  => din_int_a,
      in1   => s_position_a,
      out1  => s_position_b,
      clk   => clk,
      rst_p => rst_p);
 
  -- Now we can select channels surrounding the maximum
    data_sel_1: entity work.data_sel
      generic map (
        N_SIDE_CHANS => C_N_SIDE_CHANS)
      port map (
        dins  => din_int_a,
        dout  => sel_data,
        sel   => s_position_b.position,
        clk   => clk,
        rst_p => rst_p);
 
  -- Now for the selected channels we should calculate the charge and the
  -- weighted charge
 
  -- Generate the data multiplied by weigth (single clock delay)
  pws1: process (clk) is
  begin  -- process pws1
    if clk'event and clk = '1' then     -- rising clock edge
      if rst_p = '1' then               -- synchronous reset (active high)
        wgt_sel_data <=  C_CALC_SEL_DATA_INIT;
      else
        for i in 0 to 2*C_N_SIDE_CHANS loop
          wgt_sel_data.data_vec(i) <= resize((i-C_N_SIDE_CHANS) * signed(sel_data.data_vec(i)),C_CALC_SUM_WIDTH);
        end loop;  -- i
        -- pragma translate_off
        wgt_sel_data.lateq_mrk <= sel_data.lateq_mrk;
        -- pragma translate_on        
      end if;
    end if;
  end process pws1;
 
  -- Map the selected data to the calc type (no delay)
  pws2: process(sel_data) is
  begin  -- process pws2
    for i in 0 to 2*C_N_SIDE_CHANS loop
      s_sel_data.data_vec(i) <= resize(signed(sel_data.data_vec(i)), C_CALC_SUM_WIDTH);
    end loop;  -- i
    -- pragma translate_off
    s_sel_data.lateq_mrk <= sel_data.lateq_mrk;
    -- pragma translate_on        
  end process pws2;
 
  -- Here we calculate the sum of charge
  tree_adder_1: entity work.tree_adder
    generic map (
      N_OF_ALL_INS => 2*C_N_SIDE_CHANS+1
      )
    port map (
      dins => s_sel_data,
      dout => chrg_sum,
      clk  => clk,
      rst_p  => rst_p);
  -- Here we calculate weighted sum of charge
  tree_adder_2: entity work.tree_adder
    generic map (
      N_OF_ALL_INS => 2*C_N_SIDE_CHANS+1
      )
    port map (
      dins => wgt_sel_data,
      dout => wgt_chrg_sum,
      clk  => clk,
      rst_p  => rst_p);
  -- Now we have to equalize delays between the position, the sum
  -- of charge, and the weighted sum of charge
  ex1_eq_calc_1: entity work.ex1_eq_calc
    generic map (
      LEQ_ID => "LCEQ2")
    port map (
      in0   => s_position_b,
      out0  => s_position_c,
      in1   => chrg_sum,
      out1  => chrg_sum_b,
      in2   => wgt_chrg_sum,
      out2  => wgt_chrg_sum_b,
      clk   => clk,
      rst_p => rst_p);
 
  -- Now connect the output signals
  charge <= chrg_sum_b.sum;
  wgt_charge <= wgt_chrg_sum_b.sum;
  position <= s_position_c.position;
end architecture beh;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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