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

Subversion Repositories lateq

[/] [lateq/] [trunk/] [hdl_single_type/] [src/] [ex1_proc.vhd] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 wzab
-------------------------------------------------------------------------------
2
-- Title      : Example 1 - data processor
3
-- Project    : 
4
-------------------------------------------------------------------------------
5
-- File       : ex1_proc.vhd
6
-- Author     : Wojciech M. Zabolotny  <wzab01@gmail.com>
7
-- Company    :
8
-- License    : BSD
9
-- Created    : 2015-09-07
10
-- Last update: 2015-09-24
11
-- Platform   : 
12
-- Standard   : VHDL'93/02
13
-------------------------------------------------------------------------------
14
-- Description: This file implements the data processor which demonstrates
15
--              the methodology of automatic latency balancing in VHDL
16
--              implemented pipelined blocks
17
-------------------------------------------------------------------------------
18
-- Copyright (c) 2015 
19
-------------------------------------------------------------------------------
20
-- Revisions  :
21
-- Date        Version  Author  Description
22
-- 2015-09-07  1.0      wzab    Created
23
-------------------------------------------------------------------------------
24
library IEEE;
25
use IEEE.STD_LOGIC_1164.all;
26
use IEEE.NUMERIC_STD.all;
27
library work;
28
use work.lateq_pkg.all;
29
use work.ex1_pkg.all;
30
use work.ex1_trees_pkg.all;
31
 
32
entity ex1_proc is
33
 
34
  port (
35
    din        : in  T_INPUT_DATA;      -- data from the detector
36
    position   : out T_USER_DATA;       -- integral part of the hit position
37
    wgt_charge : out T_USER_DATA;       -- weighted hit charge (for calculation
38
    -- of fractional part of position)
39
    charge     : out T_USER_DATA;       -- hit charge
40
    clk        : in  std_logic;         -- system clock
41
    rst_p      : in  std_logic);        -- reset
42
 
43
end entity ex1_proc;
44
 
45
architecture beh of ex1_proc is
46
 
47
  -- Input data in internal form
48
  signal din_int                              : T_USER_DATA_SET(0 to C_N_CHANNELS-1) := (others => C_USER_DATA_MRK_INIT);
49
  -- pragma translate_off
50
  -- Time marker
51
  signal s_lateq_mrk                          : T_LATEQ_MRK                          := C_LATEQ_MRK_INIT;
52
  -- pragma translate_on
53
  signal sel                                  : integer;
54
  -- Maximum position converted to the common format
55
  signal dout_max                             : T_USER_DATA_MRK                      := C_USER_DATA_MRK_INIT;
56
  -- Input data with position of maximum - for first synchronizer
57
  signal din_and_pos_max_i, din_and_pos_max_o : T_USER_DATA_SET(0 to C_N_CHANNELS)   := (others => C_USER_DATA_MRK_INIT);
58
  -- Selected data (around maximum)
59
  signal sel_data                             : T_USER_DATA_SET(0 to 2*C_N_SIDE_CHANS);
60
  -- Selected data multiplied by distance from maximum
61
  signal wgt_sel_data                         : T_USER_DATA_SET(0 to 2*C_N_SIDE_CHANS);
62
  -- results 
63
  signal chrg_sum, wgt_chrg_sum               : T_USER_DATA_MRK                      := C_USER_DATA_MRK_INIT;
64
  -- Results record (for second synchroniser)
65
  signal results_i, results_o                 : T_USER_DATA_SET(0 to 2);
66
 
67
begin  -- architecture beh
68
 
69
  -- Process which generates the time markers for the input data
70
  -- It is unclear. Should it be here, or in the testbench?
71
 
72
  pgm1 : process (clk) is
73
  begin  -- process pgm1
74
    if clk'event and clk = '1' then     -- rising clock edge
75
      if rst_p = '1' then               -- synchronous reset (active low)
76
        -- pragma translate_off
77
        s_lateq_mrk <= C_LATEQ_MRK_INIT;
78
        -- pragma translate_on
79
        din_int     <= (others => C_USER_DATA_MRK_INIT);
80
      else
81
        for i in 0 to C_N_CHANNELS-1 loop
82
          din_int(i).data      <= din(i);
83
          din_int(i).valid     <= true;
84
          -- pragma translate_off
85
          din_int(i).lateq_mrk <= s_lateq_mrk;
86
 
87
        -- pragma translate_on                  
88
        end loop;  -- i
89
        -- pragma translate_off
90
        s_lateq_mrk <= lateq_mrk_incr(s_lateq_mrk);
91
        -- pragma translate_on      
92
      end if;
93
    end if;
94
  end process pgm1;
95
 
96
  -- The first block is the maximum finder.
97
  max_finder_1 : entity work.max_finder
98
    generic map (
99
      N_OF_ALL_INS => C_N_CHANNELS
100
      )
101
    port map (
102
      dins  => din_int,
103
      dout  => dout_max,
104
      clk   => clk,
105
      rst_p => rst_p);
106
  -- Now we should correct delays between the input data
107
  -- and output of the maximum finder
108
  -- So we have our delay adjustment block with two channels
109
  --
110
  din_and_pos_max_i <= din_int & dout_max;
111
 
112
  ex1 : entity work.lateq
113
    generic map (
114 4 wzab
      LEQ_ID => "LCEQ1",
115 2 wzab
      NCHANS => C_N_CHANNELS+1
116
      )
117
    port map (
118
      din   => din_and_pos_max_i,
119
      dout  => din_and_pos_max_o,
120
      clk   => clk,
121
      rst_p => rst_p);
122
 
123
  -- Now we can select channels surrounding the maximum
124
  data_sel_1 : entity work.data_sel
125
    generic map (
126
      N_SIDE_CHANS => C_N_SIDE_CHANS)
127
    port map (
128
      dins  => din_and_pos_max_o(0 to C_N_CHANNELS-1),
129
      dout  => sel_data,
130
      sel   => din_and_pos_max_o(C_N_CHANNELS),
131
      clk   => clk,
132
      rst_p => rst_p);
133
 
134
  -- Now for the selected channels we should calculate the charge and the
135
  -- weighted charge
136
 
137
  -- Generate the data multiplied by weigth (single clock delay)
138
  pws1 : process (clk) is
139
  begin  -- process pws1
140
    if clk'event and clk = '1' then     -- rising clock edge
141
      if rst_p = '1' then               -- synchronous reset (active high)
142
        wgt_sel_data <= (others => C_USER_DATA_MRK_INIT);
143
      else
144
        for i in 0 to 2*C_N_SIDE_CHANS loop
145
          wgt_sel_data(i)      <= sel_data(i);
146
          -- Overwrite the data
147
          wgt_sel_data(i).data <= resize((i-C_N_SIDE_CHANS) * signed(sel_data(i).data), C_USER_DATA_WIDTH);
148
        end loop;  -- i
149
      end if;
150
    end if;
151
  end process pws1;
152
 
153
  -- Here we calculate the sum of charge
154
  tree_adder_1 : entity work.tree_adder
155
    generic map (
156
      N_OF_ALL_INS => 2*C_N_SIDE_CHANS+1
157
      )
158
    port map (
159
      dins  => sel_data,
160
      dout  => chrg_sum,
161
      clk   => clk,
162
      rst_p => rst_p);
163
 
164
  -- Here we calculate weighted sum of charge
165
  tree_adder_2 : entity work.tree_adder
166
    generic map (
167
      N_OF_ALL_INS => 2*C_N_SIDE_CHANS+1
168
      )
169
    port map (
170
      dins  => wgt_sel_data,
171
      dout  => wgt_chrg_sum,
172
      clk   => clk,
173
      rst_p => rst_p);
174
 
175
  -- Now we have to equalize delays between the position, the sum
176
  -- of charge, and the weighted sum of charge
177
  results_i(0) <= din_and_pos_max_o(C_N_CHANNELS);
178
  results_i(1) <= chrg_sum;
179
  results_i(2) <= wgt_chrg_sum;
180
 
181
  ex2 : entity work.lateq
182
    generic map (
183 4 wzab
      LEQ_ID => "LCEQ2",
184 2 wzab
      NCHANS => 3
185
      )
186
    port map (
187
      din   => results_i,
188
      dout  => results_o,
189
      clk   => clk,
190
      rst_p => rst_p);
191
 
192
  -- Now connect the output signals
193
  charge     <= results_o(1).data;
194
  wgt_charge <= results_o(2).data;
195
  position   <= results_o(0).data;
196
end architecture beh;

powered by: WebSVN 2.1.0

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