# . APPENDIX -- C: VHDL CODE FOR THE MAIN DATA PATH AND DETAILED MEMORY MAP FOR THE DOWNLOADED PARAMETERS 

# .1: MAIN MEMORY DECODER

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- This block decodes the main memory space

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- The initialization of the standard library files

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--This revision 2B to modify the test lut data to 18 bits

\--Shweta Lolage: 10/05/2000

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--entity
main_memory_decoder is

port (clock,reset: in std_logic;

main_address:in std_logic_vector(14 downto 0);

main_data_in: in std_logic_vector(31 downto 0);

main_select,main_read,main_write: in std_logic;

monitor_data_in,misc_parameters_data_in:in std_logic_vector(31 downto
0);

gainoffset_data_in: in std_logic_vector(7 downto 0);

roadlut_data_in : in std_logic_vector (21 downto 0);

testlut_data_in: in std_logic_vector(17 downto 0);

registered_data: out std_logic_vector(31 downto 0);

registered_address: out std_logic_vector(14 downto 0);

monitor_enable,misc_parameters_enable,

gainoffset_enable,testlut_enable,roadlut_enable : out std_logic;

global_write_not_read,global_dataoutput_enable: out std_logic;

main_data_out: out std_logic_vector(31 downto 0)

);

end entity main_memory_decoder;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--Architecture body

architecture logic of main_memory_decoder is

\--

\-- define memory map for address bits 14 downto 12

\--

constant monitor_address_space:std_logic_vector(2 downto 0) := \"0000\";

constant misc_address_space: std_logic_vector(2 downto 0) := \"0001\";

constant gainoffset_address_space0: std_logic_vector(2 downto 0) :=
\"0010\";

constant gainoffset_address_space1: std_logic_vector(2 downto 0) :=
\"0011\";

constant gainoffset_address_space2: std_logic_vector(2 downto 0) :=
\"0100\";

constant gainoffset_address_space3: std_logic_vector(2 downto 0) :=
\"0101\";

constant test_address_space: std_logic_vector(2 downto 0) := \"0110\";

\-\-- define constants for zero\'s to increase bit width of above memory
space

constant zero8: std_logic_vector(7 downto 0) := \"00000000\";

constant zero10: std_logic_vector(9 downto 0) := \"0000000000\";

constant zero14: std_logic_vector(13 downto 0) := \"00000000000000\";

constant zero15: std_logic_vector(14 downto 0) := \"000000000000000\";

constant zero24: std_logic_vector(23 downto 0) :=
\"000000000000000000000000\";

constant zero23: std_logic_vector(22 downto 0) :=
\"00000000000000000000000\";

constant zero32 : std_logic_vector(31 downto 0) :=
\"00000000000000000000000000000000\";

\--

\-- Define constants to determine if this is a read or write mode

\--

constant read_mode: std_logic := \'0\';

constant write_mode: std_logic := \'1\';

constant disabled: std_logic := \'0\';

constant enabled: std_logic := \'1\';

\-\-- define signals to latch all external inputs

signal nmain_address,pmain_address: std_logic_vector(14 downto 0);

signal nmain_data_in,pmain_data_in: std_logic_vector(31 downto 0);

signal
nmain_read,pmain_read,nmain_write,pmain_write,nmain_select,pmain_select:
std_logic;

begin

\-- This process block sets the enables for each address space if this
smt channel has been selected

process(main_address,pmain_select)

variable address: std_logic_vector(3 downto 0);

variable vmonitor,vmisc,vgainoffset,vtestlut,vroadlut: std_logic;

variable vdata_out: std_logic_vector(31 downto 0);

variable memory_area_select : std_logic;

\-- this signal is to differentiate between the memory for memories on
the chip

\-- and the road data memory outside the chips

begin

\-- set default outputs

vmonitor := \'0\';

vmisc := \'0\';

vgainoffset := \'0\';

vtestlut := \'0\';

vroadlut := \'0\';

vdata_out := zero32;

address := main_address(12 downto 10);

\-- only need top 4 bits for address decoding

\-- Dr. Perry I have made this change according to the memory map we
discussed

memory_area_select := main_address(13);

\-- if select line was high during last cycle then immediately enable
appropriate address space

if(pmain_select = \'1\') then

if (memory_area_select = \'0\') then

case address is

when monitor_address_space =\>

vmonitor := \'1\';

vdata_out := monitor_data_in;

when misc_address_space =\>

vmisc := \'1\';

vdata_out := misc_parameters_data_in;

when gainoffset_address_space0\|gainoffset_address_space1 =\>

vgainoffset := \'1\';

vdata_out := zero24&gainoffset_data_in;

when gainoffset_address_space2\|gainoffset_address_space3 =\>

vgainoffset := \'1\';

vdata_out := zero24&gainoffset_data_in;

when test_address_space =\>

vtestlut := \'1\';

vdata_out := zero14&testlut_data_in;

when others =\>

null;

end case;

else

vroadlut := \'1\';

vdata_out := zero10&roadlut_data_in;

end if;

end if;

monitor_enable \<= vmonitor;

misc_parameters_enable \<= vmisc;

gainoffset_enable \<= vgainoffset;

testlut_enable \<= vtestlut;

roadlut_enable \<= vroadlut;

main_data_out \<= vdata_out;

end process;

\-\-- This process block is used to prepare data internally for read or
write

process(main_address,main_data_in,main_select,main_read,main_write,

pmain_select,pmain_write)

variable vaccess_mode,vgoe: std_logic;

begin

\-- set default outputs

nmain_address \<= main_address;

nmain_data_in \<= main_data_in;

nmain_select \<= main_select;

nmain_read \<= main_read;

nmain_write \<= main_write;

vaccess_mode := write_mode; \-- default access mode to write mode

vgoe := disabled; \-- default global oe to disabled

\-- if not selected then we are in read mode

\--

if(pmain_select = \'0\') then

vaccess_mode := read_mode;

vgoe := disabled; \-\-- we are not selected turn off global output
enable

elsif(pmain_write = \'1\') then

vaccess_mode := write_mode;

vgoe := disabled;

> \-- we are selected but writing, turn off global output enable

else

vaccess_mode := read_mode;

vgoe := enabled;

> \-- we are selected and reading, turn on global output enable

end if;

global_dataoutput_enable \<= vgoe;

global_write_not_read \<= vaccess_mode;

end process;

\-\--

\-\-- This is the register block

\-\--

process(clock,reset,nmain_select,nmain_address,nmain_data_in,nmain_read,

> nmain_write)

begin

if(reset = \'0\') then

pmain_select \<= \'0\';

pmain_address \<= zero15;

pmain_data_in \<= zero32;

pmain_read \<= \'0\';

pmain_write \<= \'0\';

elsif(clock=\'1\' and clock\'event) then

pmain_select \<= nmain_select;

pmain_address \<= nmain_address;

pmain_data_in \<= nmain_data_in;

pmain_read \<= nmain_read;

pmain_write \<= nmain_write;

end if;

end process;

registered_data \<= pmain_data_in;

registered_address \<= pmain_address;

end architecture logic;

## C.2: MISCELLANEOUS MEMORY DECODER  {#c.2-miscellaneous-memory-decoder .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- This block decodes the misc memory space

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- The initialization of the standard library files

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

entity misc_memory_decoder is

port (main_address:in std_logic_vector(10 downto 0);

bad_channel_data,misc_parameters_data:in std_logic_vector(31 downto 0);

chip_range_data,dedx_data: in std_logic_vector(23 downto 0);

> cluster_data:in std_logic_vector(16 downto 0);
> bad_channel_enable,chip_range_enable,dedx_enable,misc_parameters_enable,
>
> cluster_enable: out std_logic;

misc_data_out: out std_logic_vector(31 downto 0)

);

end entity misc_memory_decoder;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--Architecture body

architecture logic of misc_memory_decoder is

\--

\-- define memory map for address bits 11 downto 8

\--

constant bad_channel_address_space:std_logic_vector(2 downto 0) :=
\"000\";

constant chip_range_address_space: std_logic_vector(2 downto 0) :=
\"001\";

constant dedx_address_space: std_logic_vector(2 downto 0) := \"010\";

constant misc_parameters_address_space: std_logic_vector(2 downto 0) :=
\"011\";

constant cluster_address_space: std_logic_vector(2 downto 0) := \"100\";

constant zero8: std_logic_vector(7 downto 0):= \"00000000\";

constant zero15: std_logic_vector(14 downto 0):= \"000000000000000\";

constant zero32 : std_logic_vector(31 downto 0):=
\"00000000000000000000000000000000\";

begin

\-- This process block sets the enables for each address space

process(main_address)

variable address: std_logic_vector(2 downto 0);

variable vbc,vcr,vdedx,vmp,vce: std_logic;

begin

\-- set default outputs

vbc := \'0\';

vcr := \'0\';

vdedx := \'0\';

vmp := \'0\';

vce := \'0\';

address := main_address(9 downto 7);

> \-- only need top 3 bits for address decoding

case address is

when bad_channel_address_space =\>

vbc := \'1\';

when chip_range_address_space =\>

vcr := \'1\';

when dedx_address_space =\>

vdedx := \'1\';

when misc_parameters_address_space =\>

vmp := \'1\';

when cluster_address_space =\>

vce := \'1\';

when others =\>

null;

end case;

bad_channel_enable \<= vbc;

chip_range_enable \<= vcr;

dedx_enable \<= vdedx;

misc_parameters_enable \<= vmp;

cluster_enable \<= vce;

end process;

\-\-- use top three bits of address to mux correct data word out

with main_address(10 downto 8) select

misc_data_out \<= bad_channel_data when \"000\",

zero8&chip_range_data when \"001\",

zero8&dedx_data when \"010\",

misc_parameters_data when \"011\",

zero15&cluster_data when \"100\",

zero32 when others;

end architecture logic;

## C.3: PULSE THRESHOLD CONTROL {#c.3-pulse-threshold-control .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- This block decodes the memory addresses for the 8 de/dx parameters

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Initial Design: Reginald Perry (07/23/2000)

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- The initialization of the standard library files

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

entity dedx_threshold_control is

port (control_address: in std_logic_vector(5 downto 0);

> \-- address from the control block

logic_address : in std_logic_vector(1 downto 0);

> \-- for chiprange design the logic address is always 0

write_enable, memory_enable : in std_logic;

> \-- read request signal from the control block

block0,block1,block2,block3: in std_logic_vector(23 downto 0);

> \-- this is the block input data

read_address : out std_logic_vector(5 downto 0);

> \-- the mux control or logic read_address to the FIFO

write_not_read0,write_not_read1,write_not_read2,

> write_not_read3 : out std_logic;

block_out: out std_logic_vector(23 downto 0)

> \-- this is the block data out

);

end entity dedx_threshold_control;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--Architecture body

architecture logic of dedx_threshold_control is

signal control_memory_select: std_logic_vector(1 downto 0);

begin

\-- let\'s use a with select to mux read address line

\-- use a separate mux for each memory block

\-- This is block 0 addresses 0-4

\-- need two bits for address

with memory_enable select

> \-\-- use global_memory_enable to pick read_address

read_address \<= logic_address when \'0\',

control_address(1 downto 0) when \'1\',

logic_address when others;

\-- Define control memory select value

control_memory_select \<= control_address(3)&control_address(2);

\-- use a process block to determine write_not_read lines

process(memory_enable,write_enable,control_memory_select,block0,block1,block2,

block3)

variable block_data : std_logic_vector(23 downto 0);

variable write_access_required: std_logic;

begin

\-\-- use another variable to decide if write access is required

write_access_required := memory_enable and write_enable;

if(write_access_required = \'1\') then

> \-\-- need to determine which block wants access

case control_memory_select is

when \"00\" =\>

write_not_read0 \<=\'1\';

write_not_read1 \<=\'0\';

write_not_read2 \<=\'0\';

write_not_read3 \<=\'0\';

when \"01\" =\>

write_not_read0 \<=\'0\';

write_not_read1 \<=\'1\';

write_not_read2 \<=\'0\';

write_not_read3 \<=\'0\';

when \"10\" =\>

write_not_read0 \<=\'0\';

write_not_read1 \<=\'0\';

write_not_read2 \<=\'1\';

write_not_read3 \<=\'0\';

when \"11\" =\>

write_not_read0 \<=\'0\';

write_not_read1 \<=\'0\';

write_not_read2 \<=\'0\';

write_not_read3 \<=\'1\';

when others =\> \-- should never come here

write_not_read0 \<=\'0\';

write_not_read1 \<=\'0\';

write_not_read2 \<=\'0\';

write_not_read3 \<=\'0\';

end case;

else \-- this a read cyle, set all write_not_read lines low;

write_not_read0 \<=\'0\';

write_not_read1 \<=\'0\';

write_not_read2 \<=\'0\';

write_not_read3 \<=\'0\';

end if;

\-- use another case statement as a mux to set block_data out

case control_memory_select is

when \"00\" =\>

block_data := block0;

when \"01\" =\>

block_data := block1;

when \"10\" =\>

block_data := block2;

when \"11\" =\>

block_data := block3;

when others =\>

block_data := block0;

end case;

block_out \<= block_data;

end process;

end architecture logic;

## C.4: PULSE MEMORY CONCATENATION {#c.4-pulse-memory-concatenation .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- This block concatinates dedx values into one 36 bit word

\-- Include the possiblility for a three bit de/dx but don\'t do
anything with those values now

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Initial Design: Reginald Perry (07/03/2000)

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

entity dedx_memory_concatination is

port (block0,block1,block2,block3 : in std_logic_vector(23 downto 0);

dedx_threshold_coarse: out std_logic_vector(35 downto 0);

dedx_threshold_fine: out std_logic_vector(47 downto 0)

);

end entity dedx_memory_concatination;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--Architecture body

\-- memory map

\-- dedx_threshold_coarse has coarse level approximations (2 bits)

\-- dedx_threshold_fine gives one additional bit between coarse levels

\-- Example: note high is (23 downto 12) while low is (11 downto 0)

\-- coarse fine

\-- max FFF

\-- block3_high

\-- block1_low

\-- block3_low

\-- block0_high

\-- block2_high

\-- block0_low

\-- block2_low

\-- min 000

architecture logic of dedx_memory_concatination is

begin

dedx_threshold_coarse(35 downto 24) \<= block1(11 downto 0);

dedx_threshold_coarse(23 downto 0) \<= block0;

dedx_threshold_fine \<= block3&block2;

end architecture logic;

## C.5: CLUSTER THRESHOLD CONTROL {#c.5-cluster-threshold-control .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Version 0 This block is used to decide between the read address from
the

\-- control module or from the logic

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Initial Design: Shweta Lolage (07/03/2000)

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--

\-- Modified 7/20/2000 Simplify logic RJP

\-- The initialization of the standard library files

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

entity cluster_threshold_control is

port (control_address: in unsigned(1 downto 0);

> \-- address from the control block

logic_address : in unsigned(1 downto 0);

> \-- for chiprange design the logic address is always 0

write_enable, memory_enable : in std_logic;

> \-- read request signal from the control block

read_address : out unsigned(1 downto 0);

> \-- the mux output read_address to the FIFO

write_not_read : out std_logic

);

end entity cluster_threshold_control;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--Architecture body

architecture logic of cluster_threshold_control is

begin

\-- let\'s use a with select to mux read address line

\-- we only have 3 types so set top three bits of address space equal to
zero

with memory_enable select \-\-- use test_enable to pick read_address

read_address \<= logic_address when \'0\',

control_address when \'1\',

logic_address when others;

\-- use simple data_path statement for write_not_read

\-\-- write_not_read is write_enable and test_enable

write_not_read \<= memory_enable and write_enable;

end architecture logic;

## C.6: CHIP RANGE CONTROL {#c.6-chip-range-control .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Version 0 This block is used to decide between the read address from
the

\-- control module or from the logic

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Initial Design: Shweta Lolage (07/03/2000)

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--

\-- Modified 7/20/2000 Simplify logic RJP

\-- The initialization of the standard library files

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

entity chiprange_control is

port (control_address: in unsigned(5 downto 0);

> \-- address from the control block

write_enable, memory_enable : in std_logic;

> \-- read request signal from the control block

read_address : out unsigned(1 downto 0);

> \-- the mux output read_address to the FIFO

write_not_read : out std_logic

);

end entity chiprange_control;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--Architecture body

architecture logic of chiprange_control is

constant logic_address: unsigned(5 downto 0) := \"000000\";

begin

\-- let\'s use a with select to mux read address line

with memory_enable select \-\-- use test_enable to pick read_address

read_address \<= logic_address(1 downto 0) when \'0\',

control_address(1 downto 0) when \'1\',

logic_address(1 downto 0) when others;

\-- use simple data_path statement for write_not_read

\-\-- write_not_read is write_enable and test_enable

write_not_read \<= memory_enable and write_enable;

end architecture logic;

## C.7: MISCELLANEOUS DOWNLOADED PARAMETER SPLITTER {#c.7-miscellaneous-downloaded-parameter-splitter .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- This block splits the 32 bit long misc downloaded parameter word
into

\-- individual blocks

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Initial Design: Reginald Perry (07/03/2000)

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

entity misc_downloaded_parameter_splitter is

port (data_in : in std_logic_vector(31 downto 0);

dp_test_bit,dp_disable_bit: out std_logic;

dp_smt_id: out std_logic_vector(2 downto 0);

dp_delay_count,dp_seq_id: out std_logic_vector(7 downto 0);

dp_hdi_id: out std_logic_vector(2 downto 0)

);

end entity misc_downloaded_parameter_splitter;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--Architecture body

architecture logic of misc_downloaded_parameter_splitter is

begin

dp_test_bit \<= data_in(28);

dp_disable_bit \<= data_in(27);

dp_smt_id \<= data_in(26 downto 24);

dp_delay_count \<= data_in(23 downto 16);

dp_seq_id \<= data_in(15 downto 8);

dp_hdi_id \<= data_in(2 downto 0);

end architecture logic;

## C.8: TEST DATA CONTROL {#c.8-test-data-control .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Version 0 This block is used to decide between the read address from
the

\-- control module or from the logic

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Initial Design: Shweta Lolage (07/03/2000)

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--

\-- Modified 7/20/2000 Simplify logic RJP

\-- The initialization of the standard library files

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

entity testdata_control is

port (control_address: in unsigned(7 downto 0);

> \-- address from the control block

logic_address : in unsigned(7 downto 0);

> \-- address form the logic for the bad channels

write_enable, test_enable : in std_logic;

> \-- read request signal from the control block

read_address : out unsigned(7 downto 0);

> \-- the mux output read_address to the FIFO

write_not_read : out std_logic

);

end entity testdata_control;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--Architecture body

architecture logic of testdata_control is

constant zero11 : unsigned (10 downto 0):= \"00000000000\";

begin

\-- let\'s use a with select to mux read address line

with test_enable select \-\-- use test_enable to pick read_address

read_address \<= logic_address when \'0\',

control_address when \'1\',

logic_address when others;

\-- use simple data_path statement for write_not_read

\-\-- write_not_read is write_enable and test_enable

write_not_read \<= test_enable and write_enable;

end architecture logic;

## C.9: BAD CHANNEL CONTROL {#c.9-bad-channel-control .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Version 0 This block is used to decide between the read address from
the

\-- control module or from the logic

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Initial Design: Shweta Lolage (07/03/2000)

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Modified 7/20/2000 Simplify logic RJP

\-- The initialization of the standard library files

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

entity badchannel_control is

port (control_address: in unsigned(10 downto 0);

> \-- address from the control block

logic_address : in unsigned(10 downto 0);

> \-- address form the logic for the bad channels

write_enable, memory_enable : in std_logic;

> \-- read request signal from the control block

read_address : out unsigned(10 downto 0);

> \-- the mux output read_address to the FIFO

write_not_read : out std_logic

);

end entity badchannel_control;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--Architecture body

architecture logic of badchannel_control is

begin

\-- let\'s use a with select to mux read address line

with memory_enable select \-\-- use test_enable to pick read_address

read_address \<= logic_address when \'0\',

control_address when \'1\',

logic_address when others;

\-- use simple data_path statement for write_not_read

\-\-- write_not_read is write_enable and test_enable

write_not_read \<= memory_enable and write_enable;

end architecture logic;

## C.10: BAD CHANNEL MULTIPLEXER {#c.10-bad-channel-multiplexer .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Version 1 This code decodes the data for the bad channels as the
data

\-- from the control is down loaded in set of 32 words, with each word
representing

\-- the status of 32 channels. This logic finds out the individual
channel status.

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Initial Design: Shweta Lolage (6/27/2000)

\-- Simplify Logic: RJP (7/21/2000)

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Initializations to the standard library files

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

entity bad_channel_mux is

port (data_word : in unsigned (31 downto 0);

address : in integer range 31 downto 0;

bad_channel_status : out std_logic

);

end entity bad_channel_mux;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--Architectural body of the design

architecture logic of bad_channel_mux is

begin

\-- use with select to mux

with address select

bad_channel_status \<= data_word(0) when 0,

data_word(1) when 1,

data_word(2) when 2,

data_word(3) when 3,

data_word(4) when 4,

data_word(5) when 5,

data_word(6) when 6,

data_word(7) when 7,

data_word(8) when 8,

data_word(9) when 9,

data_word(10) when 10,

data_word(11) when 11,

data_word(12) when 12,

data_word(13) when 13,

data_word(14) when 14,

data_word(15) when 15,

data_word(16) when 16,

data_word(17) when 17,

data_word(18) when 18,

data_word(19) when 19,

data_word(20) when 20,

data_word(21) when 21,

data_word(22) when 22,

data_word(23) when 23,

data_word(24) when 24,

data_word(25) when 25,

data_word(26) when 26,

data_word(27) when 27,

data_word(28) when 28,

data_word(29) when 29,

data_word(30) when 30,

data_word(31) when 31,

data_word(0) when others;

end architecture logic;

## C.11: GAIN OFFSET CONTROL {#c.11-gain-offset-control .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Version 0 This block is used to decide between the read address from
the

\-- control module or from the logic

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Initial Design: Shweta Lolage (07/03/2000)

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--

\-- Modified 7/20/2000 Simplify logic RJP

\-- The initialization of the standard library files

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

entity gainoffset_control is

port (control_address: in unsigned(11 downto 0);

> \-- address from the control block

logic_address : in unsigned(11 downto 0);

> \-- address form the logic for the bad channels

write_enable, memory_enable : in std_logic;

> \-- read request signal from the control block

read_address : out unsigned(11 downto 0);

> \-- the mux output read_address to the FIFO

write_not_read : out std_logic

);

end entity gainoffset_control;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--Architecture body

architecture logic of gainoffset_control is

begin

\-- let\'s use a with select to mux read address line

with memory_enable select \-\-- use test_enable to pick read_address

read_address \<= logic_address when \'0\',

control_address when \'1\',

logic_address when others;

\-- use simple data_path statement for write_not_read

\-\-- write_not_read is write_enable and test_enable

write_not_read \<= memory_enable and write_enable;

end architecture logic;

## C.11: SMT DATA FILTER {#c.11-smt-data-filter .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Revision 2.1 SMT Data Filter

\-- Based on 5/26/2000 Document \-- Earle, Specifications for One
Channel of the STC Logic

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Initial Design: Reginald J. Perry (6/4/2000)

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Modified 6/22/00 based on new specs: Reginald J. Perry

\-- Add 18 bit output (double byte wide)

\-- Modified 7/14/00 RJP

\-- Add delay counter for event number

\-- Modified 8/02/00 Shweta Lolage

\-- to change the format of the smt_out to fit the specifications

\-- and minor changes to filter the excess C0\'s

\-- Modified 10/05/00 Shweta Lolage

\-- to remove the test inputs as they will be mux-ed with the FIFO
output

\-- to go directly to the Strip reader control

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- This block filters raw SMT data before it is stored in the input
FIFO

\-- Complex delay counter currently does not fit. Implement simple delay
counter for now

\--

\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

entity smt_data_filter is

port (delay_in: in unsigned(7 downto 0);

> \-- this is the delay in FRC start signal

frc_start: in std_logic;

> \-- this indicates that FRC data has arrived

disable: in std_logic;

> \-\-- this bit is used to turn off the channel

event_in: in unsigned(7 downto 0); \-- this is the event number

reset,clock,cav,dav,lnkrdy,smt_error_in: in std_logic;

smt_in: in unsigned(7 downto 0);

end_of_event: out std_logic; \-- specifies the end of event

smt_out: out unsigned(17 downto 0);

wrreq: out std_logic

);

end entity smt_data_filter;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--Architecture
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

architecture logic_design of smt_data_filter is

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--Signal and constant
Declaration\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

signal delay_eq_zero,tdelay: std_logic;

signal nserr,pserr: std_logic; \-- this bit is used to record the serr

signal nsmt_out,psmt_out: unsigned(17 downto 0);

> \-- this register is used to hold smt data

signal ndelay,pdelay: unsigned(7 downto 0);

> \-- this is the internal delay counter

constant zero18: unsigned(17 downto 0) := \"000000000000000000\";

constant zero8: unsigned(7 downto 0) := \"00000000\";

constant zero_address: unsigned(7 downto 0) := \"00000000\";

constant zC0: unsigned(7 downto 0) := \"11000000\";

type mystates is (s0,s1,s2,s3,s4);

signal ns,ps,ndcs,pdcs: mystates;

begin

\-- need two states to write data

process(ps, psmt_out,smt_error_in,cav,dav,lnkrdy,event_in,pdelay,pserr)

variable vsmt_enabled: std_logic;

variable vsmt_in,vupper,vlower: unsigned(7 downto 0);

begin

\-- set default outputs

ns \<= ps;

nserr \<= pserr;

end_of_event \<= \'0\';

nsmt_out \<= psmt_out;

vupper := psmt_out(15 downto 8); \-- this is the last data byte

vsmt_in := smt_in; \-- use variable to hold the input stream data.

\-- this is the real data

\-\-- SMT data is valid if

\-\-- dav = lnkrdy=0 and cav=1 and enable = 1 and disable = 0

\-\-- use a simple logic expression for this. Save in a variable

vsmt_enabled := (not dav) and (not lnkrdy) and cav and (not disable);

\-- if channel is active then access the state machine

if (vsmt_enabled= \'1\') then

case ps is

when s0 =\>

> \-\-- this state is also used to initialize the delay counter. See
> process delay_counter

end_of_event \<= \'0\';

wrreq \<= \'0\';

nsmt_out(17) \<= smt_error_in;

nsmt_out(15 downto 8) \<= vsmt_in;

> \-- this reads the upper byte of the word

\--

\-- we were told that you can\'t start up with C0s.

\-- So no need to filter them here

\-- go immediately to s1

\--

ns \<= s1;

when s1 =\>

\-- this is the lower byte

\-- If upper byte is C0 then go to s2 to wait for delay counter to be
zero to write event number

\-- into trailer

end_of_event \<= \'0\';

if(vupper = zC0) then

ns \<= s2;

wrreq \<= \'0\';

else

\-- we have not seen trailer C0 in upper byte, use smt_in for lower
byte.

wrreq \<= \'0\'; \-\-- we will enable output FIFO in next state

\-\-- use this state to load register

vlower := vsmt_in;

end_of_event \<= \'0\'; \-- we are not at end of event

ns \<= s3;

> \-- use s3 to write current word to FIFO and read next upper byte

nsmt_out(7 downto 0) \<= vlower;

nsmt_out(16) \<= smt_error_in;

end if;

\-- this is the end of the current channel,

\-- must wait for delay_eq_zero to assert before writing trailer

when s2 =\>

end_of_event \<= \'0\';

wrreq \<= \'0\';

> \-\-- need to wait in here for delay to go to zero

nsmt_out \<= \'1\'&pserr&zC0&event_in;

> \-- need to use dummy state to actually write FIFO. See s3 below

if(delay_eq_zero = \'1\') then

> \-- write out the trailer if delay is zero

\-- for the trailer, use msb for eof and use the next bit for serr

ns \<= s4; \-- go back to s0 and start over

else

ns \<= s2;

end if;

when s3 =\>

> \-- use this state to write last word and read next upper byte
>
> \-- for non end of event

end_of_event \<= \'0\';

> \-- set serr based on two error bits and current value of serr.
> \-\-\-- Use boolean equation

nserr \<= psmt_out(17) or psmt_out(8) or pserr;

wrreq \<= \'1\';

> \-- wrreq is not latched so it goes high immediately when we enter
>
> \-- s3. Data word will be latched on the next clock edge. Timing
>
> \-- is a bit problematic here because new
>
> \-- dataword is being written at the same time. Therefore, \--
>
> \-- output FIFO must latch on

\-- rising edge of clock when wrreq is enabled.

nsmt_out(17) \<= smt_error_in;

nsmt_out(15 downto 8) \<= vsmt_in;

> \-- this reads the next upper byte of the word

ns \<= s1; \-- go to s1 to see if this is a C0

when s4 =\> \-- this is the write for an end of event

end_of_event \<= \'1\';

wrreq \<= \'1\';

if( vsmt_in = zC0) then

\-- if the next byte after the end of event is still C0 then wait in
this state

\-- till you get anything other than C0.

ns \<= s4;

else

ns \<= s0; \-- go to s0 to reset delay counter

end if;

when others =\> \-- should never come here

ns \<= s0;

end case;

else

\-- if channel goes off or we are disabled, reset to s0

wrreq \<= \'0\';

end_of_event \<= \'0\';

ns \<= s0;

end if;

end process;

\-- This process block implements the simple \"delay\" counter. Not
exactly sure what it is used for RJP

delay_counter: process(pdelay, ps, delay_in,frc_start,pdcs)

variable temp_delay: std_logic;

variable i: integer;

begin

ndelay \<= pdelay;

ndcs \<= pdcs;

> \-- use a variable to determine if current count is zero

temp_delay := \'0\';

for i in 7 downto 0 loop

temp_delay := temp_delay or pdelay(i);

> \-- OR all bits to determine if we are at zero

end loop;

tdelay \<= temp_delay;

\-- this is the main state machine for delay counter

case pdcs is

when s0 =\>

> \-\-- we are waiting to start the counter in this state

delay_eq_zero \<= \'0\';

ndelay \<= delay_in;

ndcs \<= s0; \-- come back here if channel is inactive

if(ps=s1) then

ndcs \<= s1; \-- smt data has started counter

end if;

if(frc_start = \'1\') then

ndcs \<= s4; \-\-- frc_start has started counter

end if;

\-- For simple delay counter, we will only have three states.

when s1 =\>

delay_eq_zero \<= \'0\';

if(tdelay = \'0\') then

ndcs \<= s3; \-- go to s3 to set delay_eq_zero = 1

else

ndelay \<= pdelay - 1; \-- decrement ndelay

ndcs \<= s1; \-- come back to this state

end if;

if(frc_start = \'1\') then \-\-- should be able to combine with above
but synth tool choked on this

ndcs \<= s3;

end if;

\-- in this state we set delay_eq_zero = 1 and hold it until main FSM
resets by \-- going back to s0

when s3 =\>

delay_eq_zero \<= \'1\';

\-- check if main FSM is in s0, if so reset this FSM to S0 otherwise
stay here

if(ps = s0) then

ndcs \<= s0;

else

ndcs \<= s3;

end if;

\--

\-- use smt data to stop counter

\--

when s4 =\>

delay_eq_zero \<= \'0\';

if(tdelay = \'0\') then

ndcs \<= s3; \-- go to s3 to set delay_eq_zero = 1

else

ndelay \<= pdelay - 1; \-- decrement ndelay

ndcs \<= s4; \-- come back to this state

end if;

if(ps=s1) then \-\-- should be able to combine with above but synth tool
choked on this

ndcs \<= s3;

end if;

when others =\> \-- should never come here

ndcs \<= s0;

delay_eq_zero \<= \'0\';

end case;

end process;

\-- register block

reg: process(ns,ndcs,nsmt_out,clock,reset,ndelay,nserr)

begin

if(reset = \'0\') then

ps \<= s0;

pdcs \<= s0;

psmt_out \<= zero18;

pdelay \<= zero8;

pserr \<= \'0\';

elsif (clock\'event and clock=\'1\') then

ps \<= ns;

pdcs \<= ndcs;

psmt_out \<= nsmt_out;

pdelay \<= ndelay;

pserr \<= nserr;

end if;

end process reg;

smt_out \<= psmt_out; \-- this goes to the output fifo

end architecture logic_design; \--End of architecture block

## C.12: SMT TEST SELECT {#c.12-smt-test-select .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Version 0 This block is used to decide between the read address from
the

\-- control module or from the logic

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Initial Design: Shweta Lolage (10/05/2000)

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- The initialization of the standard library files

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

entity smt_test_select is

port (clock,reset : in std_logic;

test_data, fifo_data : in unsigned (17 downto 0);

l3_raw_data_eof : in std_logic;

\-- this signal is taken from the strip reader control

event_start, test , read_data: in std_logic;

> \-- event start is the main signal which indicates start of an \--

\-- event for the channel

> \-- test input this indicates whether the strip reader is going to
>
> \-- process real data

\-- or this event is a test run

> \-- read data is the signal from the strip reader
>
> \-- to read the next 18 bit word

fifo_empty : in std_logic; \-- signal from the smt fifo;

logic_address : out unsigned(7 downto 0); \-- for test lut

strip_reader_data : out unsigned (17 downto 0);

read_fifo, memory_fifo_empty : out std_logic

\-- read_req signal to the FIFO

\-- fifo or memory empty signal for strip reader

);

end entity smt_test_select;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--Architecture body

architecture logic of smt_test_select is

type mystates is (stest,sstart,sfirst,saddress);

signal ps, ns : mystates;

signal naddress, paddress : unsigned (7 downto 0);

signal read_test : std_logic;

\-- signal indicating to increment the address for next word

signal int_test : std_logic;

\-- this signal is used to latch the test signa

\-- I am not sure whether this signal

\-- will remain high all the time test data is running

\-- or will be a pulse indicating test mode

signal test_lut_empty : std_logic;

constant zero8 : unsigned(7 downto 0) := \"00000000\";

constant zero18 : unsigned (17 downto 0) := \"000000000000000000\";

constant max_count : unsigned (7 downto 0) := \"11111111\";

begin

main: process (ps,test,event_start,paddress)

begin

naddress \<= paddress;

case ps is

when stest =\>

int_test \<= \'0\';

\-- check for the test input to go to the next state

if (test = \'1\') then

int_test \<= \'1\';

ns \<= sstart;

else

int_test \<= \'0\';

ns \<= stest;

end if;

when sstart =\>

\-- initialize the adddress and the testlut empty signal

naddress \<= zero8;

test_lut_empty \<= \'0\';

if(event_start = \'1\') then

ns \<= sfirst;

else

ns \<= sstart;

end if;

when sfirst =\>

\-- this the word read out of the test lut

if(read_test = \'1\') then

naddress \<= zero8; \-- this just to make sure that the first word is
read out

ns \<= saddress;

else

ns \<= sfirst;

end if;

when saddress =\>

\-- the machine will remain in this state till the reset signal comes in

if(read_test = \'1\') then

naddress \<= paddress + 1;

else

naddress \<= paddress;

end if;

if (l3_raw_data_eof = \'0\') then

ns \<= saddress;

else

ns \<= stest;

end if;

when others =\>

ns \<= stest;

end case;

end process main;

process(int_test,read_data)

variable vread_test, vread_fifo : std_logic;

begin

if (ps = sfirst or ps = saddress) then

vread_test := read_data;

vread_fifo := \'0\';

else

vread_test:= \'0\';

vread_fifo:= read_data;

end if;

read_test \<= vread_test;

read_fifo \<= vread_fifo;

end process;

reg: process (clock,reset,ps, paddress)

begin

if (reset = \'0\') then

ps \<= stest;

paddress \<= zero8;

elsif( clock\'event and clock =\'1\') then

ps \<= ns;

paddress \<= naddress;

end if;

end process;

\-- with select to mux read data

with int_test select \-\-- use test_enable to pick read_address

strip_reader_data \<= fifo_data when \'0\',

test_data when \'1\',

zero18 when others;

with int_test select \-\-- use test_enable to pick read_address

memory_fifo_empty \<= fifo_empty when \'0\',

test_lut_empty when \'1\', \-- this just a dummy signal

\'0\' when others;

logic_address \<= paddress;

end architecture logic;

## C.13: STRIP READER CONTROL {#c.13-strip-reader-control .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Revision 2.1 Strip Reader Control

\-- Based on 6-22-00 Document

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Modified by Shweta Lolage(04-10-2000)

\-- Modified by Reginald Perry (6-4-2000)

\-- Add comments and fix up notation

\-- Add some monitoring counters

\-- Modified by Reginald Perry (6-5-2000)

\-- Add additional monitoring counters

\-- Modified by Reginald Perry (6-22-2000)

\-- Add 18 bit SMT input

\-- Modified by Reginald Perry (7-12-2000)

\-- Add monitor clear input

\-- Add chip monitor counters

\-\-- Modified by RJP (7/21/2000)

\-- Need to add rawdata l3 output

\-- Modified to add the initial state by Shweta Lolage (09-07-2000)

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

library cluster_package;

use cluster_package.cluster_package.all;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- This block defines the inputs and outputs of the counter -

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

entity strip_reader_control is

> port(reset,clock,input_fifo_empty,output_fifo_full,monitor_clear,
>
> event_start : in std_logic;

smt_in: in unsigned(2 downto 0);

bad_channel_data :in std_logic;

> \-- bad channel data is read from a rom

stream_in: in unsigned(17 downto 0);

> \-- MSB of stream_in is Error bit from SMT channel

seqid: in unsigned(7 downto 0);

hdiid: in unsigned(2 downto 0);

corrected_data:in unsigned (7 downto 0);

> \-\-- this is input data_type parameteric data in the format \-\-- of
> axial, stereo, and ninety_degrees
>
> \-\-- (low followed by high)

data_range_in: in unsigned(23 downto 0);\-- start of output data

oread,owrite:out std_logic;

> \-- signals used to enable input and output fifo

ostate :out unsigned(3 downto 0);

bad_channel_address:out unsigned(10 downto 0);

chip_data : out unsigned (11 downto 0);

output:out unsigned (22 downto 0);

> \-- monitoring data

l3_correcteddata: out unsigned(24 downto 0);

> \-- note l3_out(22) is the end of event bit

chip_monitor: out chip_array;

smt_monitor: out smt_array;

l3_rawdata: out unsigned(17 downto 0);

l3_rawdata_eof,l3_rawdata_enable: out std_logic

);

end entity strip_reader_control;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--Architecture
Begining\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

architecture logic_design of strip_reader_control is

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--Signal and constant
Declaration\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

signal neof,peof,nmismatchbit,pmismatchbit,pbc,nbc,nserr,pserr:
std_logic;

signal pnew_event,nnew_event: std_logic;

signal n_new_data_flag,p_new_data_flag: std_logic;

signal nseq_id,pseq_id: unsigned(7 downto 0);

signal nhdi_id,phdi_id: unsigned(2 downto 0);

signal noutput,poutput : unsigned (22 downto 0);

signal nchip_id,pchip_id : unsigned (3 downto 0);

signal nchan_id,pchan_id : unsigned (6 downto 0) ;

signal ndata_type, pdata_type: unsigned(1 downto 0);

signal nstate, pstate : unsigned(3 downto 0);

signal nbad_channel_address, pbad_channel_address: unsigned(10 downto
0);

signal nchip_data,pchip_data : unsigned (11 downto 0);

\-\-\-\--

\-\-- These signals are for monitoring information

\-\--

signal nsmt_mismatch_count,psmt_mismatch_count,nsmt_error_count,

psmt_error_count: unsigned(23 downto 0);

signal nsmt_zero_error,psmt_zero_error,nl3_trailer,

> pl3_trailer: unsigned(23 downto 0);

\-- These signals are used in the clear operation for the monitor
counters.

signal nchip,pchip: chip_array; \-- chip array is defined in
cluster_package

constant zero9 : unsigned (8 downto 0) := \"000000000\";

constant zero8 : unsigned (7 downto 0) := \"00000000\";

constant zero7 : unsigned (6 downto 0) := \"0000000\";

constant zero4 : unsigned (3 downto 0) := \"0000\";

constant zero3 : unsigned (2 downto 0) := \"000\";

constant C0 : unsigned (7 downto 0) := \"11000000\";

constant zero2 : unsigned (1 downto 0) := \"00\";

constant initial_state : unsigned (3 downto 0):= \"0000\";

constant first_read_state : unsigned (3 downto 0):= \"0001\";

constant seq_hdi_state : unsigned (3 downto 0):= \"0010\";

constant chip_zero_state : unsigned (3 downto 0):= \"0011\";\-- State
constants

constant chan_value_state : unsigned (3 downto 0):= \"0100\";

constant wait_for_data_state : unsigned (3 downto 0):= \"0101\";

constant correctvalue_state : unsigned (3 downto 0):= \"0110\";

constant write_fifo_state : unsigned (3 downto 0):= \"0111\";

constant read_fifo_state : unsigned (3 downto 0):= \"1000\";

constant read_wait_state : unsigned (3 downto 0):= \"1001\";

constant zero23 : unsigned (22 downto 0) := \"00000000000000000000000\";

constant zero24 : unsigned (23 downto 0) :=
\"000000000000000000000000\";

constant high : std_logic := \'1\';

constant low : std_logic := \'0\';

\-- constant

constant chip0 : unsigned(3 downto 0) := \"0000\";

constant chip1 : unsigned(3 downto 0) := \"0001\";

constant chip2 : unsigned(3 downto 0) := \"0010\";

constant chip3 : unsigned(3 downto 0) := \"0011\";

constant chip4 : unsigned(3 downto 0) := \"0100\";

constant chip5 : unsigned(3 downto 0) := \"0101\";

constant chip6 : unsigned(3 downto 0) := \"0110\";

constant chip7 : unsigned(3 downto 0) := \"0111\";

constant chip8 : unsigned(3 downto 0) := \"1000\";

constant chip9 : unsigned(3 downto 0) := \"1001\";

\-- valid data types are now defined in cluster package

\--constant undefined_type: unsigned(1 downto 0) := \"00\";

\--constant stereo_type : unsigned(1 downto 0) := \"01\";

\--constant axial_type: unsigned(1 downto 0) := \"10\";

\--constant ninety_degrees_type: unsigned(1 downto 0) := \"11\";

\-- to define the states of the decoder \--

type mystates is
(sinit,sfirst_word,seq_hdi,chip_zero,chan_value,wait_for_data,fill_output_fifo,

write_fifo,read_fifo,read_wait);

signal ns,ps,nrs,prs : mystates;

type event_states is (sinit,snew_event,swait1,swait2,sevent);

signal nevent_state,pevent_state: event_states;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--Block
Begins\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

begin

process(pstate,ps,prs,poutput,pchip_id,pchan_id,p_new_data_flag,pdata_type,

corrected_data,peof,pseq_id,phdi_id,bad_channel_data,seqid,hdiid,

input_fifo_empty,psmt_mismatch_count,psmt_zero_error,pmismatchbit,

output_fifo_full,pchip,monitor_clear,pbc,pserr,pnew_event)

\-\-- Variable declaration \-\--

\-\-- Use variables to much of the state information. Need to include a
definition table (RJP 6/4/00)

variable voutput : unsigned ( 22 downto 0);

variable vnew_data_flag,vend_of_event: std_logic;

variable verror_high,verror_low: unsigned(0 downto 0);

variable vchip_id : unsigned(3 downto 0);

variable vchan_id: unsigned(6 downto 0);

variable vstream_high_byte,vstream_low_byte,vseq_id: unsigned(7 downto
0);

variable vhdi_id: unsigned(2 downto 0);

variable vdata_type:unsigned(1 downto 0);

variable next_state,return_state: mystates;

variable vstate : unsigned(3 downto 0);

variable veof,vbc,vserr: std_logic;

begin

\--

\-- Default Outputs

\--

\--

\-- Default variable values

\--

vstate := pstate;

vnew_data_flag := p_new_data_flag;

next_state := ps;

voutput := poutput;

veof := peof;

vdata_type := pdata_type;

vchip_id := pchip_id;

vchan_id := pchan_id;

vseq_id := pseq_id;

vhdi_id := phdi_id;

vbc := pbc;

vserr := pserr;

verror_high(0) := stream_in(17);

verror_low(0) := stream_in(16);

vstream_high_byte := stream_in(15 downto 8); \-- MSB of stream data

vstream_low_byte := stream_in(7 downto 0); \-- LSB of stream data

return_state := prs;

nchip_data \<= pchip_data;

\-\-- smt counters

nsmt_mismatch_count \<= psmt_mismatch_count;

nsmt_zero_error \<= psmt_zero_error;

nmismatchbit \<= pmismatchbit;

nbad_channel_address \<= pchip_id&pchan_id;

> \-- this is used to address bad channel prom

\--

\-- Chip counters \-- default outputs

\--

nchip \<= pchip;

\--

\-- Check for serr

\--

vserr := verror_high(0) or verror_low(0) or pserr;

\-- set l3_rawdata to defaults.

l3_rawdata \<= stream_in;

l3_rawdata_eof \<= \'0\';

l3_rawdata_enable \<= \'0\';

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-\-\--CASE STATEMENT \--

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- The following case statment will look at the incoming stream of data
and \--will proceed to

\-- compare and check for the validity of the same. For each case
different actions will occur.

\-- Note1: Every state requires to have a read fifo before it can
proceed to check the information.

\-- Note2: After the channel state and 11-bit word composed of the chip
and channel id are sent to

\-- to an lpm rom, which will send an 9 bit word back into the decoder.
From this 9 bit word we

\-- will look at the MSB and if it is \"0\" then we know that the
channel is ok.

\-- Note3: Only the channel and Value state will have the command to
enable writing to the FIFO.

CASE ps IS

\-- the initial state in which the FSM is waiting for the event start

When sinit =\>

vstate := initial_state;

if (event_start = \'1\') then

next_state := sfirst_word;

else

next_state := sinit;

end if;

\-- the initial state in which the first word is read outof the fifo

when sfirst_word =\>

vstate := first_read_state;

if (pevent_state = sevent) then

next_state := read_fifo;

return_state := seq_hdi;

else

next_state := sfirst_word;

end if;

\-- Sequence State

\-- Check for correct sequence ID and hdi_id \--

WHEN seq_hdi =\>

vstate := seq_hdi_state;

\-- variable used to check current state this is for debugging only

next_state := read_fifo;

return_state := chip_zero;

vnew_data_flag := high;

> \-- set new data high when looking for seqid and hdiid

vseq_id := vstream_high_byte; \-- save the sequence id

vhdi_id := vstream_low_byte(2 downto 0);

> \-\-- save the hdi id. It is bits 2,1,0

nmismatchbit \<= low; \-- reset mismatch bit

if((vstream_high_byte /= seqid) or (vstream_low_byte /= hdiid)) then

> \--when stream does not equal the preset value

\-- need to count the number of errors in seq_Id mismatch

nsmt_mismatch_count \<= psmt_mismatch_count + 1;

nmismatchbit \<= high; \-- set the mismatch bit high

end if;

\-- need to enable l3_rawdata so that l3 will latch when we change
states

l3_rawdata_eof \<= \'0\';

l3_rawdata_enable \<= \'1\';

\-- CHIP State

\-- Check for correct chip ID and zero_byte

WHEN chip_zero =\>

vstate := chip_zero_state;

next_state := read_fifo;

if(vstream_low_byte /= zero7) then

> \-- check that low byte is zero

nsmt_zero_error \<= psmt_zero_error + 1;

end if;

if (vstream_high_byte(7) = high) then

> \-\-- if MSB = 1 this is a new chip. Save chip ID

vchip_id := vstream_high_byte(3 downto 0);

> \-- and return to channel value

return_state := chan_value;

else

return_state := chip_zero;

> \-\-- If MSB is not 1 then error come back to this state

end if; \-\-- and look for valid chip id

\-- need to save l3 raw

l3_rawdata_eof \<= \'0\';

l3_rawdata_enable \<= \'1\';

\-- CHANNEL State \--

\-- Get Channel ID and Value from Stream

WHEN chan_value =\> \-- The channel ID is read from stream

vstate := chan_value_state; \--

next_state := read_fifo;

return_state := chan_value;

veof := \'0\';

if (vstream_high_byte = C0) then

> \-- if channel is C0 then we are at the end of event

veof := high;

> \-- event number is in low_byte so save it in voutput

voutput(18 downto 11) := vstream_low_byte;

next_state := fill_output_fifo;

> \-- jump to fill_output_fifo

return_state := sinit;

> \-- return to next sequence ID after write fifo

l3_rawdata_enable \<= \'1\';

l3_rawdata_eof \<= \'1\'; \-- set end of event bit

elsif (vstream_high_byte(7) = \'1\') then

> \-- This means this is a new chip ID

next_state := chip_zero;

> \-- Check for a new type of chip. Do NOT read fifo.

l3_rawdata_enable \<= \'0\'; \-- do not write into l3

l3_rawdata_eof \<= \'0\';

else

next_state := wait_for_data;

> \-- this is a regular channel/data pair

vchan_id := vstream_high_byte(6 downto 0);

> \-- need to goto a wait state to give LUT enough

nchip_data \<= pchip_id&vstream_low_byte;

> \-- time to access corrected data

l3_rawdata_eof \<= \'0\';

l3_rawdata_enable \<= \'1\'; \-- enable l3 rawdata

end if; \-- come back here after write

\-- wait for data State \--

\-- This is a dummy state to wait for the corrected data to come from
the LUT.

WHEN wait_for_data =\>

vstate := wait_for_data_state;

next_state := fill_output_fifo;

> \-- go to fill output fifo state

\-\--

\-\-- Data is valid, Increment chip monitor counters here

\--

\-- Chip counters \-- default outputs

\--

nchip \<= pchip;

case vchip_id is

when chip0 =\>

nchip(0) \<= add_one(pchip(0));

when chip1 =\>

nchip(1) \<= add_one(pchip(1));

when chip2 =\>

nchip(2) \<= add_one(pchip(2));

when chip3 =\>

nchip(3) \<= add_one(pchip(3));

when chip4 =\>

nchip(4) \<= add_one(pchip(4));

when chip5 =\>

nchip(5) \<= add_one(pchip(5));

when chip6 =\>

nchip(6) \<= add_one(pchip(6));

when chip7 =\>

nchip(7) \<= add_one(pchip(7));

when chip8 =\>

nchip(8) \<= add_one(pchip(8));

when others =\>

nchip \<= pchip; \-\-- should never come here;

end case;

\-- DO NOT enable l3 raw here

l3_rawdata_eof \<= \'0\';

l3_rawdata_enable \<= \'0\';

WHEN fill_output_fifo =\>

vstate := correctvalue_state;

\-- This is a bit backward but if veof leave voutput(18 downto 11) only.
This was set in chan_value state

\-- if not end of event that check for a bad channel and replace with
zero if true

\-- otherwise use corrected data in output. Hopefully, the synthesis
tool can clean this up

if(peof = \'1\') then

voutput(18 downto 11) := voutput(18 downto 11);

> \-- if at end of event, leave voutput only but reset vserr;

elsif(bad_channel_data = \'1\') then

> \-- bad channel LUT is access using pchip_id and pchannel_id

voutput(18 downto 11) := zero8;

> \-- this channel is bad, replace data with zero

else

voutput(18 downto 11) := corrected_data;

> \-- not eof and channel good, replace with

end if; \-- corrected data

voutput(22 downto 21) := pdata_type;

voutput(20) := p_new_data_flag;

voutput(19) := peof;

voutput(10 downto 7) := pchip_id;

voutput(6 downto 0) := pchan_id;

vnew_data_flag := low;

\--

\-- save bad channel data for l3

\--

vbc := bad_channel_data;

next_state := write_fifo;

\-- DO NOT enable l3 raw here

l3_rawdata_eof \<= \'0\';

l3_rawdata_enable \<= \'0\';

\-- write_fifo State \--

WHEN write_fifo =\>

vstate := write_fifo_state; \-\-- this is for debugging

vnew_data_flag := low;

> \-- reset new data flag after first write.

if(output_fifo_full = \'1\') then

next_state := write_fifo;

else

next_state := read_fifo;

> \-- fifo is free to write into. Next state should be calling state

if(peof = \'1\') then \-- if end of event, reset vserr

vserr := low; \--

end if;

end if;

\-- bring l3_rawdata low in here

l3_rawdata_eof \<= \'0\';

l3_rawdata_enable \<= \'0\';

\--read_fifo state

when read_fifo =\>

vstate := read_fifo_state;

if(input_fifo_empty = \'1\') then

next_state := read_fifo; \-- fifo is empty. need to wait

else

next_state := return_state;

end if;

\-- bring l3_rawdata low in here

l3_rawdata_eof \<= \'0\';

l3_rawdata_enable \<= \'0\';

\-- OTHERS \-- \-- should never come here

WHEN OTHERS =\>

next_state := sinit;

return_state := sinit;

l3_rawdata_eof \<= \'0\';

l3_rawdata_enable \<= \'0\';

END CASE;

\-- if monitor_clear, need to reset monitor counters)

if(monitor_clear = \'1\') then

for i in 8 downto 0 loop

nchip(i) \<= zero_monitor_word;

end loop;

nsmt_mismatch_count \<= zero24;

nsmt_zero_error \<= zero24;

end if;

\-- set the next state of signal to their respective variable signals

nstate \<= vstate;

n_new_data_flag \<= vnew_data_flag;

nrs \<= return_state;

ns \<= next_state;

noutput \<= voutput;

neof \<= veof;

nchip_id \<= vchip_id;

nchan_id \<= vchan_id;

nseq_id \<= vseq_id;

nhdi_id \<= vhdi_id;

nbc \<= vbc;

nserr \<= vserr;

end process;

\-- The following two process block work concurrently with the above
process block. One

\-- block reads raw data from the input FIFO process block and the other
write corrected data

\-- to the write FIFO process block

\-- Read fifo block

\-- This process block reads raw data from the input fifo

process(ps,input_fifo_empty)

> \-- This process is used to read the input fifo

variable vread: std_logic;

begin

vread := \'0\';

if(input_fifo_empty = \'1\') then

\-- Buffer is empty, therefore no read signal

vread := \'0\';

else

\--Write and read fifo process

case ps is

when read_fifo =\> \-- For any read_fifo state set read flag high

vread := \'1\';

when others =\>

vread := \'0\';

end case;

end if;

oread \<= vread; \-- output read signal is set to read variable

end process;

process(ps) \-- This process is used to write to the output fifo

variable vwrite: std_logic;

begin

vwrite := \'0\';

if(output_fifo_full = \'1\') then \-- If buffer is full, we must wait

vwrite := \'0\';

else

case ps is \--when we have a write enable signal, we will proceed

when write_fifo=\> \-- to write to the ouput fifo the 23-bit word

vwrite := \'1\';

when others =\>

vwrite := \'0\';

end case;

end if;

owrite \<= vwrite;

end process;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-\-- Use this process block to determine the type of data

\-\-- Input parameters must come from another block

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

process (data_range_in,pchip_id)

\-- use variables to break up data_range data

variable
axial_low,axial_high,stereo_low,stereo_high,ninety_low,ninety_high:
unsigned(3 downto 0);

begin

axial_low := data_range_in(3 downto 0);

axial_high := data_range_in(7 downto 4);

stereo_low := data_range_in(11 downto 8);

stereo_high := data_range_in(15 downto 12);

ninety_low := data_range_in(19 downto 16);

ninety_high := data_range_in(23 downto 20);

ndata_type \<= undefined_type;

if(pchip_id \>= axial_low and pchip_id \<= axial_high) then

ndata_type \<= axial_type;

end if;

if(pchip_id \>= stereo_low and pchip_id \<= stereo_high) then

ndata_type \<= stereo_type;

end if;

if(pchip_id \>= ninety_low and pchip_id \<= ninety_high) then

ndata_type \<= ninety_degrees_type;

end if;

end process;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-\-- This block monitors the number of times ERROR is high in the smt
data

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

process(stream_in,monitor_clear)

begin

nsmt_error_count \<= psmt_error_count;

if(monitor_clear = \'1\') then

nsmt_error_count \<= zero24;

elsif((stream_in(16) = high) or (stream_in(17) = high)) then

nsmt_error_count \<= psmt_error_count + 1;

end if;

end process;

\-\--

\-\-- This process block is used to start a new event

\-\--

process(pevent_state,peof,event_start)

begin

nnew_event \<= pnew_event;

case pevent_state is

when sinit =\>

nnew_event \<= \'0\';

if(event_start = \'1\') then

nevent_state \<= snew_event;

else

nevent_state \<= sinit;

end if;

when snew_event =\> \-- this is a new event

nnew_event \<= \'0\';

> \-- enter three wait states before reading first word

nevent_state \<= swait1; \-- this gives L3 time to write headers

when swait1 =\>

nnew_event \<= \'0\';

nevent_state \<= swait2;

when swait2 =\>

nnew_event \<= \'0\';

nevent_state \<= sevent;

when sevent =\>

nnew_event \<= \'1\';

if(peof = \'1\') then

nevent_state \<= sinit;

else

nevent_state \<= sevent;

end if;

when others =\> \-\-- never should come here

null;

end case;

end process;

\-\-- Use this process block to clear monitor signals

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-\-\-\-\-\-\-\-\-\-\-- REGISTER BLOCK
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

reg:process(clock,reset, ns, nrs,
noutput,nchip_id,nchan_id,n_new_data_flag,

ndata_type,neof,nbad_channel_address,nstate,nchip_data,nmismatchbit,

> nsmt_error_count,nsmt_mismatch_count,nsmt_zero_error,nbc,nnew_event)

begin

if (reset = \'0\') then \--Sets all outputs and counters to zero

pstate \<= initial_state;

ps \<= sinit;

prs \<= sinit;

poutput \<= zero23;

pchip_id \<= zero4;

pchan_id \<= zero7;

p_new_data_flag\<= \'0\';

pseq_id \<= zero8;

phdi_id \<= zero3;

pdata_type \<= zero2;

peof \<= \'0\';

pbc \<= \'0\';

pserr \<= \'0\';

pbad_channel_address \<= zero4&zero7;

pchip_data \<=\"000000000000\";

psmt_error_count \<= zero24;

psmt_mismatch_count \<= zero24;

psmt_zero_error \<= zero24;

pl3_trailer \<= zero24;

pmismatchbit \<= \'0\';

pnew_event \<= \'0\';

pevent_state \<= sinit;

elsif (clock\'event and clock = \'1\') then

pstate \<= nstate;

ps \<= ns;

> \--at every clock edge there will be an output

prs \<= nrs;

poutput \<= noutput;

pchip_id \<= nchip_id;

pchan_id \<= nchan_id;

p_new_data_flag\<= n_new_data_flag;

pseq_id \<= nseq_id;

phdi_id \<= nhdi_id;

pdata_type \<= ndata_type;

peof \<= neof;

pbc \<= nbc;

pserr \<= nserr;

pbad_channel_address \<= nbad_channel_address;

pchip_data \<= nchip_data;

psmt_error_count \<= nsmt_error_count;

psmt_mismatch_count \<= nsmt_mismatch_count;

psmt_zero_error \<= nsmt_zero_error;

pmismatchbit \<= nmismatchbit;

pl3_trailer \<= nl3_trailer;

pnew_event \<= nnew_event;

pevent_state \<= nevent_state;

end if;

end process reg; \--End of register block

\--

\-- register block for chip counters

\--

process(clock,reset,nchip)

begin

if(reset = \'0\') then

for i in 8 downto 0 loop

pchip(i) \<= zero_monitor_word;

end loop;

elsif(clock\'event and clock=\'1\') then

pchip \<= nchip;

end if;

end process;

\--

\-- This process block is used to form l3 word

\--

process(peof,pmismatchbit,pdata_type,poutput,pseq_id,phdi_id,pbc,smt_in,pserr,pl3_trailer)

variable vnew_data_flag,vend_of_event: std_logic;

variable vchip_id : unsigned(3 downto 0);

variable vchan_id: unsigned(6 downto 0);

variable vdata_event, vseq_id: unsigned(7 downto 0);

variable vhdi_id: unsigned(2 downto 0);

variable vdata_type:unsigned(1 downto 0);

variable veof,vbc,vmismatch,vserr: std_logic;

variable vsmt_in: unsigned(2 downto 0);

variable vl3_out: unsigned(24 downto 0);

begin

\--

\-- Use variables to help form data word

\--

vdata_type := poutput(22 downto 21);

vnew_data_flag := poutput(20);

veof := poutput(19);

vdata_event := poutput(18 downto 11);

vchip_id := poutput(10 downto 7);

vchan_id := poutput(6 downto 0);

veof := peof;

vmismatch := pmismatchbit;

vseq_id := pseq_id;

vhdi_id := phdi_id;

vsmt_in := smt_in;

vserr := pserr;

vbc := pbc;

nl3_trailer \<= vserr&vmismatch&vsmt_in&vseq_id&vhdi_id&vdata_event;

\-- if end of event we must output trailer l3 word \-\-- event number
should be in trailer

if(veof = \'1\') then

\-- 1 + 1 + 1 + 3 + 8 + 3 + 8 = 25

vl3_out := veof&vserr&vmismatch&vsmt_in&vseq_id&vhdi_id&vdata_event;

\-- 1 + 1 + 3

else

\-- 1+ 1 + 2 + 8 + 4 + 7 + 2 = 25

vl3_out := veof&vbc&vdata_type&vdata_event&vchip_id&vchan_id&\"00\";

\-- nl3_trailer \<= pl3_trailer;

end if;

l3_correcteddata \<= vl3_out;

end process;

ostate \<= pstate; \-- Ensures that we keep the outputs constant at
every cycle

output \<= poutput; \-- until a condition is met and we update the
values.

bad_channel_address \<= pbad_channel_address;

chip_data \<= pchip_data;

chip_monitor \<= pchip;

smt_monitor(0) \<= to_monitorword(pl3_trailer);

smt_monitor(1) \<= to_monitorword(psmt_error_count);

smt_monitor(2) \<= to_monitorword(psmt_mismatch_count);

smt_monitor(3) \<= to_monitorword(psmt_zero_error);

end architecture logic_design; \--End of architecture block

## C.14: MONITOR ADDRESS SPACE {#c.14-monitor-address-space .unnumbered}

\--

\-- This is the monitor address space

\-- It is 32x24

\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

library cluster_package;

use cluster_package.cluster_package.all;

\-- This package contains the following definitions

\-- smt_array is 4 x 24

\-- chip_array is 9 x 24

\-- centroid_array is 3 x 24

entity monitor_spacea is

port(address: in unsigned(9 downto 0);

monitor_latch: in std_logic;

smt_counter: in smt_array;

chipcounter: chip_array;

axial:in centroid_array;

clk,reset: in std_logic;

l3_trailer: out fifoword;

word_out: out fifoword;

monitor_clear: out std_logic

);

end entity monitor_spacea;

architecture behavior of monitor_spacea is

\--

\-- Define the following general memory map for the 1k monitor space

\--

\-- smt counters 000-00F

\-- centroid counters 010-01F

\-- chip counters 020-02F

\-- empty space 030-3FF

constant smt_address_space :unsigned(5 downto 0) := \"000000\";

constant centroid_address_space :unsigned(5 downto 0) := \"000001\";

constant chip_address_space :unsigned(5 downto 0) := \"000010\";

signal nsmt_registers,psmt_registers: smt_array;

signal nchip_registers,pchip_registers: chip_array;

signal ncentroid_registers,pcentroid_registers: centroid_array;

constant true: std_logic := \'1\';

constant false: std_logic := \'0\';

signal nmonitor_clear,pmonitor_clear: std_logic;

type smt_states is (s0,s1,s2);

signal psmt,nsmt: smt_states;

signal nword_out, pword_out: fifoword;

\--signal nbyte_out, pbyte_out: fifobyte;

begin

\--

\-- This process block attaches the monitor counters to the register
array

\-- It is enabled on the rising edge of monitor_latch

\--

process(psmt,smt_counter,chipcounter,axial,monitor_latch)

begin

\--

\-- Default outputs

\--

\-- smt_registers

\--

for i in 3 downto 0 loop

nsmt_registers(i) \<= psmt_registers(i);

end loop;

\--

\-- chip registers

\--

for i in 8 downto 0 loop

nchip_registers(i) \<= pchip_registers(i);

end loop;

\--

\-- centroid registers

\--

for i in 2 downto 0 loop

ncentroid_registers(i) \<= pcentroid_registers(i);

end loop;

\--

\-- look for the rising edge of monitor_latch

\--

case psmt is

when s0 =\>

nsmt \<= s0;

nmonitor_clear \<= \'0\';

if(monitor_latch = \'1\') then

nsmt \<= s1;

end if;

when s1 =\>

nsmt \<= s2;

nmonitor_clear \<= \'1\';

for i in 3 downto 0 loop

nsmt_registers(i) \<= smt_counter(i);

end loop;

for i in 8 downto 0 loop

nchip_registers(i) \<= chipcounter(i);

end loop;

for i in 2 downto 0 loop

ncentroid_registers(i) \<= axial(i);

end loop;

when s2 =\>

nmonitor_clear \<= \'1\';

if(monitor_latch = \'1\') then

nsmt \<= s2;

else

nsmt \<= s0;

end if;

when others =\>

nsmt \<= s0;

nmonitor_clear \<= \'0\';

end case;

end process;

\--

\-- This process block sets the data output to the addressed monitor
space

\--

process(address,psmt_registers,pchip_registers,pcentroid_registers)

variable vaddress_high: unsigned(5 downto 0);

variable vaddress_low: unsigned(3 downto 0);

variable vword_out: monitor_word;

begin

vaddress_high := address(9 downto 4);

vaddress_low := address(3 downto 0);

vword_out := zero_monitor_word;

\--

\-- use address_high to select memory space

\--

\-- use address_low to select specific word

\--

case vaddress_high is

when smt_address_space =\>

case vaddress_low is

when address0 =\>

vword_out := psmt_registers(0);

when address1 =\>

vword_out := psmt_registers(1);

when address2 =\>

vword_out := psmt_registers(2);

when address3 =\>

vword_out := psmt_registers(3);

when others =\>

vword_out := zero_monitor_word;

end case;

when chip_address_space =\>

case vaddress_low is

when address0 =\>

vword_out := pchip_registers(0);

when address1 =\>

vword_out := pchip_registers(1);

when address2 =\>

vword_out := pchip_registers(2);

when address3 =\>

vword_out := pchip_registers(3);

when address4 =\>

vword_out := pchip_registers(4);

when address5 =\>

vword_out := pchip_registers(5);

when address6 =\>

vword_out := pchip_registers(6);

when address7 =\>

vword_out := pchip_registers(7);

when address8 =\>

vword_out := pchip_registers(8);

when others =\>

vword_out := zero_monitor_word;

end case;

when centroid_address_space =\>

case vaddress_low is

when address0 =\>

vword_out := pcentroid_registers(0);

when address1 =\>

vword_out := pcentroid_registers(1);

when address2 =\>

vword_out := pcentroid_registers(2);

when others =\>

vword_out := zero_monitor_word;

end case;

when others =\>

vword_out := zero_monitor_word;

end case;

nword_out \<= to_fifoword(vword_out);

end process;

\--

\-- This process block implements the registers for the monitor space

\--

process(nsmt_registers,nchip_registers,ncentroid_registers,clk,reset)

begin

if(reset=\'0\') then

for i in 3 downto 0 loop

psmt_registers(i) \<= zero_monitor_word;

end loop;

for i in 8 downto 0 loop

pchip_registers(i) \<= zero_monitor_word;

end loop;

for i in 4 downto 0 loop

pcentroid_registers(i) \<= zero_monitor_word;

end loop;

elsif(clk=\'1\' and clk\'event) then

for i in 3 downto 0 loop

psmt_registers(i) \<= nsmt_registers(i);

end loop;

for i in 8 downto 0 loop

pchip_registers(i) \<= nchip_registers(i);

end loop;

for i in 2 downto 0 loop

pcentroid_registers(i) \<= ncentroid_registers(i);

end loop;

end if;

end process;

\--

\-- This process block implements registers

\--

process(nsmt, nmonitor_clear, clk,reset)

begin

if(reset = \'0\') then

psmt \<= s0;

pmonitor_clear \<= \'0\';

pword_out \<= zero_fifoword;

elsif(clk = \'1\' and clk\'event) then

psmt \<= nsmt;

pmonitor_clear \<= nmonitor_clear;

pword_out \<= nword_out;

end if;

end process;

\--

\-- This process block is used to construct l3 trailer

\--

process(smt_counter(0))

variable vl3temp: fifoword;

begin

vl3temp := to_fifoword(smt_counter(0));

\-\-- 5 + 2 + 3 + 22 =

l3_trailer \<= \"11110\"&vl3temp(23 downto 22)&\"000\"&vl3temp(21 downto
0);

end process;

monitor_clear \<= pmonitor_clear;

word_out \<= pword_out;

end architecture;

## C.15: CLUSTER PACKAGE {#c.15-cluster-package .unnumbered}

\-- This code is for the package- for clustering the data for the
counters

\-- this is just a package declaration common for all the other files

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

package cluster_package is

type monitor_word is array(23 downto 0) of std_logic;

type fifoword is array(31 downto 0) of std_logic;

type fifobyte is array(7 downto 0) of std_logic;

type smt_array is array(3 downto 0) of monitor_word;

type chip_array is array(8 downto 0) of monitor_word;

type centroid_array is array(2 downto 0) of monitor_word;

constant zero_monitor_word: monitor_word :=
\"000000000000000000000000\";

constant zero_fifoword: fifoword :=
\"00000000000000000000000000000000\";

constant zero_fifobyte: fifobyte := \"00000000\";

constant address0: unsigned(3 downto 0) := \"0000\";

constant address1: unsigned(3 downto 0) := \"0001\";

constant address2: unsigned(3 downto 0) := \"0010\";

constant address3: unsigned(3 downto 0) := \"0011\";

constant address4: unsigned(3 downto 0) := \"0100\";

constant address5: unsigned(3 downto 0) := \"0101\";

constant address6: unsigned(3 downto 0) := \"0110\";

constant address7: unsigned(3 downto 0) := \"0111\";

constant address8: unsigned(3 downto 0) := \"1000\";

constant address9: unsigned(3 downto 0) := \"1001\";

constant addressa: unsigned(3 downto 0) := \"1010\";

constant addressb: unsigned(3 downto 0) := \"1011\";

constant addressc: unsigned(3 downto 0) := \"1100\";

constant addressd: unsigned(3 downto 0) := \"1101\";

constant addresse: unsigned(3 downto 0) := \"1110\";

constant addressf: unsigned(3 downto 0) := \"1111\";

\-- define data_types

constant undefined_type: unsigned(1 downto 0) := \"00\";

constant stereo_type : unsigned(1 downto 0) := \"01\";

constant axial_type: unsigned(1 downto 0) := \"10\";

constant ninety_degrees_type: unsigned(1 downto 0) := \"11\";

function to_fifoword(a: fifobyte) return fifoword;

function to_fifoword(a: monitor_word) return fifoword;

function to_monitorword(a: unsigned(23 downto 0)) return monitor_word;

function add_one(a: monitor_word) return monitor_word;

end package;

package body cluster_package is

function to_fifoword(a:fifobyte) return fifoword is

variable result: fifoword;

begin

for i in 31 downto 8 loop

result(i) := \'0\';

end loop;

for i in 7 downto 0 loop

result(i) := a(i);

end loop;

return result;

end function; \--

function to_fifoword(a:monitor_word) return fifoword is

variable result: fifoword;

begin

for i in 31 downto 24 loop

result(i) := \'0\';

end loop;

for i in 23 downto 0 loop

result(i) := a(i);

end loop;

return result;

end function; \--

function to_monitorword(a:unsigned(23 downto 0)) return monitor_word is

variable result: monitor_word;

begin

for i in 23 downto 0 loop

result(i) := a(i);

end loop;

return result;

end function; \--

function add_one(a:monitor_word) return monitor_word is

variable result: monitor_word;

variable temp: unsigned(23 downto 0);

variable i: integer;

begin

for i in 23 downto 0 loop

temp(i) := a(i);

end loop;

temp := temp + 1;

for i in 23 downto 0 loop

result(i) := temp(i);

end loop;

return result;

end function; \--

end;

## C.16: CLUSTER FINDER {#c.16-cluster-finder .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Revision 2 Cluster Finder Algorithm

\-- Based on 2-15-2000 Specification Document

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Initial Design : Reginald Perry (6-12-2000)

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Add monitor counter - 7/17/2000 RJP

\-- Add end of event bit - 7/17/2000 RJP

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

library cluster_package;

use cluster_package.cluster_package.all;

entity cluster_finder is

port(data_in: in unsigned(22 downto 0);

> \-- input data word from fifo

data_threshold_1,data_threshold_2: in unsigned(7 downto 0);

> \-- read as inputs

cluster_type: in unsigned(0 downto 0);

> \-- use 3 or 5 strips in scalculation

\--

\-- altera compiler does not like unsigned without vector.

\-- Need to have two bits until

\-- we can check this out

input_fifo_empty,output_axialfifo_full,clk, reset : in std_logic;

input_fifo_read,output_axialfifo_write: out std_logic;

ad2: out unsigned(10 downto 0); \-- address bus

d1,d2,d3,d4,d5: out unsigned(7 downto 0);

current_type: out unsigned(1 downto 0); \-- current data type

end_of_event_out: out std_logic; \-- this is the end of event bit

calculation_type: out unsigned(0 downto 0);

> \-- this is the type of calculation

l3_enable: out std_logic; \-- this is used to enable l3

centroid_counters: out centroid_array;

l3out:out unsigned(31 downto 0)

);

\-- inputs for data_threshold

end entity cluster_finder;

architecture behavior of cluster_finder is

\-- define major states

type mystates is (sreset, sread,sread_fifo,sload_fifo,scheck_for_eof,

sinit,smain,snext,soutpeak,scalculate,swrite,swrite_fifo,

> sl3_wait);

type l3states is (s0,s1,s2,s3,s4,s5,s6);

\-- data types are now defined in cluster_package

\-- constant axial: unsigned(1 downto 0) := \"01\";

\-- constant stereo: unsigned(1 downto 0) := \"10\";

\-- constant z_axis: unsigned(1 downto 0) := \"11\";

\-- constant undefined: unsigned(1 downto 0) := \"00\";

signal ns, ps,nreturn_state,preturn_state: mystates;

signal nl3s,pl3s: l3states;

\-- counter used to keep track of number of strips read

signal nstrip_count, pstrip_count: unsigned(7 downto 0);

\-- signals used for data and address registers

signal nd1,nd2,nd3,nd4,nd5,ndata_shadow1,

ndata_shadow2: unsigned(7 downto 0);

signal pd1,pd2,pd3,pd4,pd5,pdata_shadow1,

pdata_shadow2: unsigned(7 downto 0);

signal nad1,nad2,nad3,nad4,nad5,naddress_shadow1,

naddress_shadow2: unsigned(10 downto 0);

signal pad1,pad2,pad3,pad4,pad5,paddress_shadow1,

paddress_shadow2: unsigned(10 downto 0);

\-- these signals are used to keep track of the current data type

signal nnext_address,pnext_address: unsigned(10 downto 0);

signal ncurrent_type,pcurrent_type: unsigned(1 downto 0);

signal nfirst_read,pfirst_read,data_compare,valid_cluster_peak:
std_logic;

signal pdata,ndata: unsigned(22 downto 0);

\-- these signals are for the end of event bit

signal neof,peof,nl3_wait,pl3_wait: std_logic;

\-\-- these signals are used for monitoring

signal naxial_counter,paxial_counter,nstereo_counter,

pstereo_counter: unsigned(23 downto 0);

signal nninety_counter, pninety_counter: unsigned(23 downto 0);

\-- l3buffer

signal pl3out,nl3out: unsigned(31 downto 0);

\-- these constants are used with the data registers

constant zero_data_reg: unsigned(7 downto 0) := \"00000000\";

constant zero_address_reg: unsigned(10 downto 0) := \"00000000000\";

constant zero23:unsigned(22 downto 0) := \"00000000000000000000000\";

constant zero24:unsigned(23 downto 0) := \"000000000000000000000000\";

constant zero32: unsigned(31 downto 0) :=
\"00000000000000000000000000000000\";

constant true: std_logic := \'1\';

constant false: std_logic := \'0\';

\--

\-- l3stuff

begin

process(ps,preturn_state,pd1,pd2,pd3,pd4,pd5,pad1,pad2,pad3,pad4,pad5,

paddress_shadow1,paddress_shadow2,pdata_shadow1,pdata_shadow2,

pnext_address,pcurrent_type,pdata,preturn_state,pfirst_read,pdata,

pstrip_count,data_compare,valid_cluster_peak,data_threshold_1,

data_threshold_2,input_fifo_empty,cluster_type,paxial_counter,

pstereo_counter,pninety_counter,pl3_wait)

variable vtype: unsigned(1 downto 0);

variable veof,vnew_data_flag,end_of_cluster: std_logic;

variable vdata: unsigned(7 downto 0);

variable vaddress: unsigned(10 downto 0);

variable vl3out:unsigned(31 downto 0);

begin

\-- set default outputs

\-- state information

ns \<= ps;

nreturn_state \<= preturn_state; \-- hold onto return state

\-- save data buffers

nd1 \<= pd1;

nd2 \<= pd2;

nd3 \<= pd3;

nd4 \<= pd4;

nd5 \<= pd5;

ndata_shadow1 \<= pdata_shadow1;

ndata_shadow2 \<= pdata_shadow2;

\-- save address buffers

nad1 \<= pad1;

nad2 \<= pad2;

nad3 \<= pad3;

nad4 \<= pad4;

nad5 \<= pad5;

naddress_shadow1 \<= paddress_shadow1;

naddress_shadow2 \<= paddress_shadow2;

\-- parse current input word in parts. Use variables for this.

vtype := pdata(22 downto 21);

vnew_data_flag := pdata(20); \-- variable defined as std_logic

veof := pdata(19); \-- variable defined as std_logic

vdata := pdata(18 downto 11);

vaddress := pdata(10 downto 0);

\-- save eof for next block

neof \<= veof;

\--

\-- set defaults for these signals

\--

ncurrent_type \<= pcurrent_type; \-- current data type

nnext_address \<= pnext_address;

nfirst_read \<= pfirst_read;

\-- flag to indicate we are coming out of a reset state

\-- this prevents a centriod calculation before the first read.

ndata \<= pdata; \-- save data

\-- This implements the main FSM

case ps is

\--

\-- Reset state

\-- This is the first state AFTER the initial reset

\--

when sreset =\>

\--

\-- Need to load data parameters here eventually.

\-- For now, just go to the first read

\--

ns \<= sread;

ncurrent_type \<= axial_type;

\-- default to axial type to give memory something to access

nreturn_state \<= sinit;

\-- this statement is really not needed since this is the first read

nfirst_read \<= true; \-- but let\'s help the synthesis tool anyway.

\-- Read state

when sread =\>

if(input_fifo_empty = true) then

ns \<= sread;

\-- fifo is empty. Need to wait for some data

else

ns \<= sread_fifo;

\-- data is ready Go to next state to read_fifo

end if;

\-- Read fifo state

\-- add this \"wait\" state to allow data to be read from input fifo

when sread_fifo =\>

ns \<= sload_fifo;

\--

\-- Data should be available at fifo. Load into an internal register
data

\--

when sload_fifo =\>

ndata \<= data_in;

ns \<= scheck_for_eof; \-- let\'s go check for the eof

\--

\-- probably we can combine sread_fifo and sload_fifo. Look at this
later

\--

\-- This state checks for an eof

\--

when scheck_for_eof =\>

\-- if veof=1 then this is the end of a cluster

\-- if veof=0 then end of cluster is initial reset to 0

end_of_cluster :=veof;

\--

\-- Check for a change of type

if(vtype /= pcurrent_type) then

end_of_cluster := true;

ncurrent_type \<= vtype; \-- save new data type as next current_type

end if;

\-- if data is less than threshold then end of cluster. Data_threshold_1
is an input

if(vdata \< data_threshold_1) then

end_of_cluster := true;

end if;

\-- if current_address /= next_address then end of cluster

\-- need to set next_address based on this outcome

if(vaddress /= pnext_address) then

end_of_cluster := true;

nnext_address \<= vaddress + 1;

else

nnext_address \<= pnext_address + 1;

end if;

\--

\-- if this is the first read then we don\'t want to store

\-- a hit in the output fifo

\--

if(pfirst_read = true) then

nfirst_read \<= false;

ns\<= sinit;

elsif(end_of_cluster = \'1\') then

\--

\-- This is the start of a new cluster.

\-- Need to calculate centroid on old cluster.

\-- The current data word will be used in the new cluster

\--

ns \<= scalculate;

nreturn_state \<= sinit;

\-- after calculate need to initialize current data word

else

ns \<= preturn_state;

\-- this is not the end of a cluster. continue cluster finding algorithm

end if;

\-- Initialization State. We are starting the search for a new cluster

when sinit =\>

\-- init data registers

nd1 \<= zero_data_reg;

nd2 \<= zero_data_reg;

nd3 \<= vdata;

nd4 \<= zero_data_reg;

nd5 \<= zero_data_reg;

\-- init address registers

nad1 \<= zero_address_reg;

nad2 \<= zero_address_reg;

nad3 \<= vaddress;

nad4 \<= zero_address_reg;

nad5 \<= zero_address_reg;

\-- init shadow registers

ndata_shadow2 \<= zero_data_reg;

ndata_shadow1 \<= zero_data_reg;

naddress_shadow2 \<= zero_address_reg;

naddress_shadow1 \<= zero_address_reg;

\-- go read the next word and return to smaim

ns \<= sread;

nreturn_state \<= smain;

\-- this is the main state. Compare the next data word to the current
cluster center

when smain =\>

\-- next state will be sread

ns \<= sread;

if(data_compare = \'1\') then

\--

\-- if data is greater than or equal to current peak then move data as
cluster peak

\-- need to shift all other data words to the left by one slot

nd1 \<= pd2;

nd2 \<= pd3;

nd3 \<= vdata;

\-- need to also shift addresses

nad1 \<= pad2;

nad2 \<= pad3;

nad3 \<= vaddress;

nreturn_state \<= smain; \-- come back to this state

else

\-- Data is less than current cluster peak. Store this value in d4.

nd4 \<= vdata;

nad4 \<= vaddress;

nreturn_state \<= snext; \-\-- need to go to snext state

end if;

\--

\-- this is the next state. This looks at the D5 register

\--

when snext =\>

\-- next state will be sread

ns \<= sread;

if(data_compare = \'1\') then

\-- if data is greater than or equal to current cluster peak

\-- shift d3 to d1 and d4 to d2 and new peak (nd3) gets vdata

\-- must also remember to zero out nd4 and nd5

nd1 \<= pd3;

nd2 \<= pd4;

nd3 \<= vdata;

nd4 \<= zero_data_reg;

nd5 \<= zero_data_reg;

\-- also need to change the addresses

nad1 \<= pad3;

nad2 \<= pad4;

nad3 \<= vaddress;

nad4 \<= zero_address_reg;

nad5 \<= zero_address_reg;

nreturn_state \<= smain;

else

\-- vdata is less than current cluster peak

\-- save vdata in nd5 also need to set up \"shawdow\" registers

nd5 \<= vdata;

nad5 \<= vaddress;

\-- need to setup shadow registers for \"out-peak\" case

ndata_shadow1 \<= pd4;

ndata_shadow2 \<= vdata;

naddress_shadow1 \<= pad4;

naddress_shadow2 \<= vaddress;

\-- return state should be out peak

nreturn_state \<= soutpeak;

end if;

\-- This is the outpeak case.

\-- That is, the current cluster address is out of the range of the

\-- cluster peak. However, we need to save the last two values in case

\-- we come across a case where

\-- vdata \> pd3.

when soutpeak =\>

\-- next state will be sread

ns \<= sread;

\--

\-- This is where we check the data against the current cluster peak

\--

if(data_compare = \'1\') then

\-- data is greater than current cluster peak.

\-- Need to move shadow registers into real registers

\-- don\'t forget to zero d4 and d5

nd1 \<= pdata_shadow1;

nd2 \<= pdata_shadow2;

nd3 \<= vdata;

nd4 \<= zero_data_reg;

nd5 \<= zero_data_reg;

\-- same goes for the addresses

nad1 \<= paddress_shadow1;

nad2 \<= paddress_shadow2;

nad3 \<= vaddress;

nad4 \<= zero_address_reg;

nad5 \<= zero_address_reg;

nreturn_state \<= smain; \-\-- return now goes to smaim

else

\--

\-- din is not greater than current peak.

\-- shift shadow registers and return to this state

\--

ndata_shadow1 \<= pdata_shadow2;

ndata_shadow2 \<= vdata;

naddress_shadow1 \<= paddress_shadow2;

naddress_shadow2 \<= vaddress;

nreturn_state \<= soutpeak;

end if;

\--

\-- This is the centriod calculate state

\-- Actually centroid is always being calculated

\-- we just need to determine if we send it on to the

\-- hit filter.

\--

when scalculate =\>

\--

\--

\--

if(valid_cluster_peak = true) then \-\-- this signal is generated by
another process block

\--

\-- need to and increment counters

case vtype is

when axial_type =\>

naxial_counter \<= paxial_counter + 1;

when stereo_type =\>

nstereo_counter \<= pstereo_counter + 1;

when ninety_degrees_type =\>

nninety_counter \<= pninety_counter + 1;

when others =\>

null;

end case;

ns \<= swrite;

else

\--

\-- this is not a valid peak. Throw away this cluster and start over

\--

ns \<= sinit;

end if;

when swrite =\>

\-- dummy state to see if output fifo is not empty

if(output_axialfifo_full = true) then

ns \<= swrite;

else

ns \<= swrite_fifo;

end if;

when swrite_fifo =\>

\-- output fifo is written during this cycle

ns \<= sl3_wait; \-- let\'s wait for l3 to finish

when sl3_wait =\>

if(pl3_wait = \'1\') then

ns \<= sl3_wait;

else

ns \<= sinit;

end if;

when others =\>

\-- we should never come here. Therefore go to sreset

ns \<= sreset;

end case;

end process;

\--

\-- this state machine is used to read a word from the input fifo

\--

process(ps)

variable vread: std_logic;

begin

vread := false;

case ps is

when sread_fifo =\>

vread := true;

when others =\>

vread := false;

end case;

input_fifo_read \<= vread;

end process;

\--

\-- this state machine is used to write a word to the output fifo

\--

process(ps)

variable vwrite: std_logic;

begin

vwrite := false;

case ps is

when swrite_fifo =\>

vwrite := true;

when others =\>

vwrite := false;

end case;

output_axialfifo_write\<= vwrite;

\-- do this as a mealy machine to save a cycle

end process;

\--

\-- This process block counts the number of strips in the current
cluster (-1)

\--

process(ps,pstrip_count)

variable vcnt : unsigned(7 downto 0);

begin

vcnt := pstrip_count;

case ps is

when sinit =\>

vcnt := zero_data_reg;

when smain\|snext\|soutpeak =\>

\-- only increment this counter when we have new data

vcnt := vcnt + 1;

when others =\>

null;

end case;

nstrip_count \<= vcnt;

end process;

\--

\-- This process block compares the data against the current peak

\--

process(pdata,pd3)

variable vdata:unsigned(7 downto 0);

begin

vdata := pdata(18 downto 11);

\--

\-- compare data word to current cluster center

\--

if(vdata \< pd3) then

data_compare \<= \'0\';

else

data_compare \<= \'1\';

end if;

end process;

\--

\-- This process block compares pd3 against data_threshold_2

\--

process(pd3,data_threshold_2)

variable vdata:unsigned(7 downto 0);

begin

vdata := pd3;

\--

\-- compare data word to current cluster center

\--

if(vdata \< data_threshold_2) then

valid_cluster_peak \<= false;

\-- current peak is less than data_threshold_2 \-- invalid peak.

else

valid_cluster_peak \<= true; \-- we have a valid peak here.

end if;

end process;

\--

\-- Register process block for state information

\--

process (ns,nreturn_state,nl3s,clk, reset)

begin

if( reset = \'0\') then

ps \<= sreset;

preturn_state \<= sreset;

pl3s \<= s0;

elsif(clk = \'1\' and clk\'event) then

ps \<= ns;

preturn_state \<= nreturn_state;

pl3s \<= nl3s;

end if;

end process;

\--

\-- Register process block for misc signals

\--

process (ncurrent_type,nnext_address, pfirst_read, clk, reset)

begin

if( reset = \'0\') then

pcurrent_type \<= undefined_type;

pnext_address \<= zero_address_reg;

pfirst_read \<= \'0\';

elsif(clk = \'1\' and clk\'event) then

pcurrent_type \<= ncurrent_type;

pnext_address \<= nnext_address;

pfirst_read \<= nfirst_read;

end if;

end process;

\--

\-- Register process block to shadow address and data registers also the
data is saved here

\--

process(nd1,nd2,nd3,nd4,nd5,nad1,nad2,nad3,nad4,nad5,nstrip_count,

nl3out,nl3_wait,naddress_shadow1,naddress_shadow2,

ndata_shadow1,ndata_shadow2,ndata, clk, reset)

begin

if( reset = \'0\') then

pd1 \<= zero_data_reg;

pd2 \<= zero_data_reg;

pd3 \<= zero_data_reg;

pd4 \<= zero_data_reg;

pd5 \<= zero_data_reg;

pad1 \<= zero_address_reg;

pad2 \<= zero_address_reg;

pad3 \<= zero_address_reg;

pad4 \<= zero_address_reg;

pad5 \<= zero_address_reg;

pdata_shadow1 \<= zero_data_reg;

pdata_shadow2 \<= zero_data_reg;

paddress_shadow1 \<= zero_address_reg;

paddress_shadow2 \<= zero_address_reg;

pdata \<= zero23;

pstrip_count \<= zero_data_reg;

pl3out \<= zero32;

peof \<= \'0\';

pl3_wait \<= \'0\';

elsif( clk\'event and clk = \'1\') then

pd1 \<= nd1;

pd2 \<= nd2;

pd3 \<= nd3;

pd4 \<= nd4;

pd5 \<= nd5;

pad1 \<= nad1;

pad2 \<= nad2;

pad3 \<= nad3;

pad4 \<= nad4;

pad5 \<= nad5;

pdata_shadow1 \<= ndata_shadow1;

pdata_shadow2 \<= ndata_shadow1;

paddress_shadow1 \<= naddress_shadow1;

paddress_shadow2 \<= naddress_shadow1;

pdata \<= ndata;

pstrip_count \<= nstrip_count;

pl3out \<= nl3out;

peof \<= neof;

pl3_wait \<= nl3_wait;

end if;

end process;

\-- Registers for counters

process(clk,reset,naxial_counter,nstereo_counter,nninety_counter)

begin

if(reset = \'0\') then

paxial_counter \<= zero24;

pstereo_counter \<= zero24;

pninety_counter \<= zero24;

elsif(clk\'event and clk=\'1\') then

paxial_counter \<= naxial_counter;

pstereo_counter \<= nstereo_counter;

pninety_counter \<= nninety_counter;

end if;

end process;

\-- this process block takes care of l3, we will need multiple cycles to
write all the data

process(ps,
pl3s,pd1,pd2,pd3,pd4,pd5,pad1,pad2,pad3,pad4,pad5,data_threshold_1,data_threshold_2,pstrip_count,

valid_cluster_peak, pcurrent_type, cluster_type)

variable vl3out: unsigned(31 downto 0);

begin

\-- default outputs

nl3_wait \<= \'0\';

vl3out := zero32;

nl3s \<= pl3s;

case pl3s is

when s0 =\>

l3_enable \<= \'0\';

if(ps = scalculate) then

nl3_wait \<= \'1\'; \-\-- tell main fsm to hold

nl3s \<= s1;

\-- need to set up first l3 output word

vl3out(31 downto 28) := \"0000\";

vl3out(27 downto 20) := data_threshold_2;

vl3out(19 downto 18) := pcurrent_type;

vl3out(17) := cluster_type(0); \-\-- only a single bit

vl3out(16 downto 9) := data_threshold_1;

vl3out(8 downto 1) := pstrip_count;

vl3out(0) := \'1\';

else

nl3_wait \<= \'0\';

nl3s \<= s0;

end if;

when s1 =\>

nl3_wait \<= \'1\';

l3_enable \<= \'1\'; \-- write the previous word into l3 using l3_enable
\--do not register

vl3out(31 downto 23) := \"000000000\";

vl3out(22 downto 21) := pcurrent_type;

vl3out(20 downto 13) := pd2;

vl3out(12 downto 2) := pad2;

vl3out(1 downto 0) := \"00\";

nl3s \<= s2;

when s2 =\>

nl3_wait \<=\'1\';

l3_enable \<= \'1\';

\-\-- write the remaining data out

vl3out(31 downto 23) := \"000000000\";

vl3out(22 downto 21) := pcurrent_type;

vl3out(20 downto 13) := pd3;

vl3out(12 downto 2) := pad3;

vl3out(1 downto 0) := \"00\";

nl3s \<= s3;

when s3 =\>

nl3_wait \<=\'1\';

l3_enable \<= \'1\';

\-\-- write the remaining data out

vl3out(31 downto 23) := \"000000000\";

vl3out(22 downto 21) := pcurrent_type;

vl3out(20 downto 13) := pd4;

vl3out(12 downto 2) := pad4;

vl3out(1 downto 0) := \"00\";

nl3s \<= s4;

when s4 =\>

nl3_wait \<=\'1\';

l3_enable \<= \'1\';

\-\-- write the remaining data out

vl3out(31 downto 23) := \"000000000\";

vl3out(22 downto 21) := pcurrent_type;

vl3out(20 downto 13) := pd5;

vl3out(12 downto 2) := pad5;

vl3out(1 downto 0) := \"00\";

nl3s \<= s5;

when s5 =\>

nl3_wait \<=\'0\'; \-- we can let main FSM restart now

l3_enable \<= \'1\';

\-\-- write the remaining data out

vl3out(31 downto 23) := \"000000000\";

vl3out(22 downto 21) := pcurrent_type;

vl3out(20 downto 13) := pd1;

vl3out(12 downto 2) := pad1;

vl3out(1 downto 0) := \"00\";

nl3s \<= s6; \-- need one more state to write out last word

when s6 =\>

nl3_wait \<=\'0\';

l3_enable \<= \'1\'; \-\-- write out last word

nl3s \<= s0;

when others =\>

null;

end case;

nl3out \<= vl3out; \-- this will save l3out for writing into l3

end process;

\-- attach address and data registers to output buffers

d1 \<= pd1;

d2 \<= pd2;

d3 \<= pd3;

d4 \<= pd4;

d5 \<= pd5;

ad2 \<= pad2;

l3out \<= pl3out;

current_type \<= pcurrent_type;

end_of_event_out \<= peof;

calculation_type \<= cluster_type;

\-- attach counters

centroid_counters(0) \<= to_monitorword(paxial_counter);

centroid_counters(1) \<= to_monitorword(pstereo_counter);

centroid_counters(2) \<= to_monitorword(pninety_counter);

end behavior;

## C.17: CENTROID CALCULATOR {#c.17-centroid-calculator .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- File: centroid_calculator.vhd

\-- Description: VHDL code to calculate the three or five strip
centroid.

\-- For the five strip case we are given five (5) eight bit values -

\-- d1,d2,d3,d4,d5

\-- The centroid is usually given by
(d1+2d2+3d3+4d4+5d5)/(d1+d2+d3+d4+d5)

\-- in this case we are shifting the result so it is centered around d2

\-- so the numerator becomes -d1+0d2+d3+2d4+3d5

\-- For the three strip case: the equation is -d1+0d2+d3/d1+d2+d3

\--

\-- Originally Created: 6/4/00

\-- (Reginald J. Perry - FAMU-FSU College of Engineering)

\-- Add l3 logic: 7/17/2000 RJP

\-- Modified : by Shweta Lolage

\-- Changes in the 3 cluster centroid calculations

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-\-- normal initialization stuff

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\--

\-- define entity

\--

entity centroid_calculator is

\--

\-- The maximum value is given by 5\*255 which will need 8+3+1=12 bits
to save \-\-- (need one bit for the sign). We\'ll assume the d\'s are
unsigned values.

\-- Therefore, we will need N+4 bits for the num and den results.

port(d1,d2,d3,d4,d5: in signed(7 downto 0);

threshold_range_in:in unsigned(35 downto 0); \-- this is threshold data

address_d2: in signed(10 downto 0);

\-- this is the original address of d2

calculation_type: in std_logic;

centroid_type: in signed(1 downto 0);

end_of_event_bit: in signed(0 downto 0);

l3_trailer: in signed(31 downto 0);

l3_out: out signed(31 downto 0);

centroid_out: out signed(17 downto 0)

);

end entity centroid_calculator;

architecture behavior of centroid_calculator is

signal num,den: signed(11 downto 0);

constant three_strip_centroid: std_logic := \'0\';

constant five_strip_centroid: std_logic := \'1\';

constant high: std_logic := \'1\';

constant low: std_logic := \'0\';

constant zero9 : signed(8 downto 0) := \"000000000\";

\-- these signals are needed by the divider circuit

\--

signal q,qint: signed(3 downto 0);

signal y3,y3m,y2,y2m,y1,y1m: signed(11 downto 0);

signal centroid,sum3,sum2,sum1,sum0: signed(12 downto 0);

\-- These signals and constants are used to calculate the quantized
pulse areas

signal centroid_pulse_area: signed(1 downto 0);

signal level1_check,level2_check,level3_check: std_logic;

signal level_check: std_logic_vector(2 downto 0);

constant level0 : signed(1 downto 0) := \"00\";

constant level1 : signed(1 downto 0) := \"01\";

constant level2 : signed(1 downto 0) := \"10\";

constant level3 : signed(1 downto 0) := \"11\";

begin

\-- This process block provides the sums for the numerator and
denominator

summer: process(d1,d2,d3,d4,d5,calculation_type)

\-- Create variables to temporarily save results

variable s1,s2,s3,s4,s5 : signed(8 downto 0);

variable temp1,temp1a,temp2,temp3 : signed(9 downto 0);

variable temp32,temp5 : signed(10 downto 0);

variable parea,temp4,temp6,temp7 : signed(11 downto 0);

variable temp1b,temp2b : signed (9 downto 0);

variable temp3b : signed (10 downto 0);

begin

\--

\-- s\'s are used to add a sign bit to the d\'s

\--

s1 := \"0\"&d1;

s2 := \"0\"&d2;

s3 := \"0\"&d3;

s4 := \"0\"&d4;

s5 := \"0\"&d5;

\-- define temporary variables needed by both the three and five strip
calculator

temp1 := s1+s2; \-- this sum will be 10 bits (d1+d2)

temp2 := s3-s1; \-- this sum will be 10 bits (d3-d1)

\-- Use two separate adders for three and five strip centroid
calculation

\-- this may save some time in the calculation

if(calculation_type = five_strip_centroid) then

temp3 := s4+s5; \-- this sum will be 10 bits (d4+d5)

temp32 := temp3&\"0\"; \-- this is 2xtemp3 = 2(d4+d5); it will be 11
bits

temp4 := (\"00\"&s5)+temp32; \-- this is 2d4 + 3d5: sum will be 12 bits

temp5 := temp1 + temp3; \-- this is d1+d2+d4+d5: sum will be 11 bits

den \<= (\"000\"&s3)+temp5; \-- this is d1+d2+d3+d4+d5: need 12 bits

temp7 := \"00\"&temp2; \-- bit extend temp2 from 10 to 12 bits

num \<= temp7+temp4; \-- this is -d1+d3+2d4+3d5: need 12 bits

else

\-- this is the three strip case. num is -d2+d4 and den = d2+d3+d4

temp1b := s4 - s2; \-- this will be num = -d2+d4

num \<= \"000\"&temp1b; \-- sign extend to 12 bits

temp2b := s2 + s4; \-- the sum of d2 + d4 , for the den

temp1a := \"00\"&d3; \-- need to sign extend d3 to add it to temp1

den \<= \"0\"&(temp2b+temp1a);

end if;

end process summer;

\-- These process blocks implements the divider circuit.

\-- The design consists of four identical process blocks with a 2x1 mux

\-- Each process calculates yx - b where yx the result from the previous

\-- process block. For the first process block, yx=a. If the result of
yx-a

\-- is greater than 0 (i.e. positive)

\-- then this result is given to the next process

\-- block otherwise yx is propagated.

\-- A mux is used to select between the two possiblities.

\--

\--

p3:process(num,den)

begin

sum3 \<= num - den;

\--

\-- the \"sign bit\" is stored in sum(12) and saved as qint(3)

\--

qint(3) \<= sum3(12);

end process;

\--

\-- if qint(3) is 1, then the result is negative and we DONT want to
keep the subtraction result

\-- in this case we\'ll send yx (num in this case) to the next process
block. If qint = 0 , then

\-- yx \>= b and we want to keep the subtraction.

\--

with qint(3) select

y3m \<= num when \'1\',

sum3(11 downto 0) when \'0\',

num when others;

\--

\-- We need to shift the result from above to the left by one bit so we
can calculate the next

\-- bit of the division. We could also accomplish this by shifting den
one bit to the right.

\--

y3 \<= y3m(10 downto 0) & \'0\';

\--

\-- This process block is identical to the above except num has been

\-- replaced with y3 and

\-- the appropriate substitutions have been made for sum, y, and qint.

\--

p2:process(y3,den)

begin

sum2 \<= y3 - den;

qint(2) \<= sum2(12);

end process;

with qint(2) select

y2m \<= y3 when \'1\',

sum2(11 downto 0) when \'0\',

y3 when others;

y2 \<= y2m(10 downto 0) & \'0\';

\--

\-- This process block is identical to the above except y3

\-- has been replaced with y2 and

\-- the appropriate substitutions have been made for sum, y, and qint.

\--

p1:process(y2,den)

begin

sum1 \<= y2 - den;

qint(1) \<= sum1(12);

end process;

with qint(1) select

y1m \<= y2 when \'1\',

sum1(11 downto 0) when \'0\',

y2 when others;

y1 \<= y1m(10 downto 0) & \'0\';

\--

\-- This process block is identical to the above except

\-- y2 has been replaced with y1 and

\-- the appropriate substitutions have been made for sum, y, and qint.

\--

p0:process(y1,den)

begin

sum0 \<= y1 - den;

qint(0) \<= sum0(12);

end process;

inv:for I in 3 downto 0 generate

q(i) \<= not qint(i);

end generate inv;

\-- q\'s now contain the result of the division.

\-- Need to add this result to the original address of d2

process(address_d2,q)

variable tempa, tempb: signed(12 downto 0);

constant zero10: signed(9 downto 0) := \"0000000000\";

begin

\-- the result should be 13 bits

\-- original 11 bits plus two extra bits

\-- let\'s use a couple of variables so we don\'t get lost

tempa := address_d2&\"00\";

tempb := zero10&q(3 downto 1);

centroid \<= tempa + tempb;

end process;

\-- This process block will calculate the two bit pulse area threshold
values

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

process (threshold_range_in,den)

\-- use variables to break up data_range data

variable level1_low,level2_low,level3_low:unsigned(11 downto 0);

variable parea:signed(1 downto 0);

constant code_level0:std_logic_vector(2 downto 0) := \"000\";

constant code_level1: std_logic_vector(2 downto 0) := \"001\";

constant code_level2: std_logic_vector(2 downto 0) := \"011\";

constant code_level3 : std_logic_vector(2 downto 0) := \"111\";

begin

\-- implement this like a coarse approximation ADC

\-- Check input data against threshold levels and then use an encoder to

\-- convert thermometer code to binary code

level1_low := threshold_range_in(11 downto 0);

level2_low := threshold_range_in(23 downto 12);

level3_low := threshold_range_in(35 downto 24);

\-- make the default level 3

level1_check \<= high;

level2_check \<= high;

level3_check \<= high;

if(den \< level1_low) then

level1_check \<= low;

end if;

if(den \< level2_low) then

level2_check \<= low;

end if;

if(den \< level3_low) then

level3_check \<= low;

end if;

level_check \<= level3_check&level2_check&level1_check;

case level_check is

when code_level0 =\>

parea := level0;

when code_level1 =\>

parea := level1;

when code_level2 =\>

parea := level2;

when code_level3 =\> \-- this is the default condition

parea := level3;

when others =\>

parea := level3;

end case;

centroid_pulse_area \<= parea;

end process;

\-- this process block is for l3 for the centroids

process(l3_trailer,address_d2,centroid_pulse_area,centroid_type,end_of_event_bit)

variable vsmt,vhdi_id: signed(2 downto 0);

variable vseq_id: signed(7 downto 0);

begin

vsmt := l3_trailer(21 downto 19);

vhdi_id := l3_trailer(10 downto 8);

vseq_id := l3_trailer(18 downto 11);

if(end_of_event_bit(0) = \'1\') then

l3_out \<= l3_trailer;

else

\-- 1+ 3 + 2 + 2 + 8 + 3 + 13 =

l3_out \<=
\"0\"&vsmt&centroid_type&centroid_pulse_area&vseq_id&vhdi_id&centroid;

end if;

end process;

\-- centroid out is the end_of_event, datatype, centroid_pulse_area and
centroid

\-- 1 + 2 + 2 + 13

centroid_out \<=
end_of_event_bit(0)&centroid_type&centroid_pulse_area&centroid;

end architecture behavior;

## C.18: HIT CONTROL BLOCK {#c.18-hit-control-block .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--File:hit_control_block.vhd

\-- To implement the control logic for the hit filter.

\-- Originally created by : Shweta Lolage date - 05/15/2000

\--Modifications by Shweta : - 06/02/2000

\-- modified by Shweta lolage on 06/15/2000 to remove all unnecessary
registered signals

\-- modified to include one state to accommodate a control signal to
read the masked register

\-- by Shweta Lolage - 09/04/2000

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-- Entity Declaration

entity hit_control_block is

port (road_write,done,event_start : in std_logic;

\-- road_write signal from the road data handler

\-- DONE signal is from the pointer block indicating

\--that it is through with the hits for that particular centroid.

\-- event \_start is a global signal marking the start of an event

clock,reset : in std_logic;

last_road : in std_logic; \--signal indicating end of road data

fifoempty : in std_logic; \-- active low signal

datatype : in std_logic_vector (2 downto 0);

\-- the end of event tagged with the datatype of the centroid

\-- coming from the centroid finder

centroid : in unsigned (12 downto 0);

\-- centroids from the centroid finder

road,mask : out unsigned (5 downto 0);

\-- the signals to the ROMs to get the corrected load road signal

\-- and final mask register

read_comp,read_hitreg,input_fifo_enable,hits_busy : out std_logic;

\--the read_comp signal is to read the output from the comparators

\-- this read_hitreg signal is to read the masked hit register

\-- the input_fifo_enable signal is a read fifo signal

> \-- to the centroid\'s fifo

\-- the hits_busy signal is to indicate that the

> \-- hitfilter has started pulling out

\-- the centroids and is busy processing hits

z_write : out std_logic; \-- fifo enable for the z-axis fifo

a_centroid_comp : out unsigned (13 downto 0);

\-- the extra bit is for the last centroid or end of event bit for the
L3

z_centroid_fifo : out unsigned (13 downto 0);

road_event_count : out unsigned (7 downto 0);

\-- this is the internal event counter for the hitfilter

count : out unsigned(5 downto 0)

\--this output indicates the number of comparators loaded with road_data

);

end entity hit_control_block;

\-- Architecture Body

architecture behavior of hit_control_block is

type states is (sevent,sfirstload,snext,sload,slast_road,sdecide,

> scentroid_write,scomp_read,shitreg_read,swait,sdata_wait);

signal ncount,pcount,vcount : unsigned (5 downto 0);

signal nstate, pstate : states;

signal nroad,proad,nmask,pmask: unsigned (5 downto 0);

signal nread_comp,pread_comp: std_logic;

signal nread_hitreg,pread_hitreg: std_logic;

signal ndone,pdone : std_logic;

signal nhits_busy,phits_busy : std_logic;

signal ninput_fifo_enable,pinput_fifo_enable,nfifoempty,pfifoempty,

nlast_road,plast_road : std_logic;

signal nroad_write,proad_write : std_logic;

signal loadin: std_logic; \--signals to load the road_data

signal nroad_event_count,proad_event_count : unsigned (7 downto 0);

signal vroad_event_count : unsigned (7 downto 0);

signal nmux_select,pmux_select : std_logic;

signal mux_select : std_logic;

signal ncentroid, pcentroid : unsigned (12 downto 0);

signal vz_centroid_fifo,va_centroid_comp : unsigned (13 downto 0);

\-- this for temporary assignment of z-centroids and axial centroids

signal nz_write,pz_write : std_logic;

signal nend_of_event, pend_of_event : std_logic;

signal nevent_end,pevent_end : std_logic;

signal nrerr,prerr : std_logic;

constant zero6 : unsigned (5 downto 0) :=\"000000\";

constant zero13 : unsigned (12 downto 0) := \"0000000000000\";

constant zero14 : unsigned (13 downto 0) := \"00000000000000\";

constant zero46 : unsigned (45 downto 0) :=
\"0000000000000000000000000000000000000000000000\";

begin

ncentroid \<= centroid;

nend_of_event \<= datatype(2);

\-- the end of event bit is tagged along with the datatype

\-- and the centroids in the input FIFO

\-- this process block is used to keep assign a track number

\-- to the incoming road data

process
(road_write,plast_road,pcount,pstate,pread_comp,done,pdone,pfifoempty,

phits_busy,pz_write)

begin

\-- initialization of the signals

ncount \<= pcount;

nread_comp \<= pread_comp;

nread_hitreg \<= pread_hitreg;

nstate \<= pstate;

ndone \<= done;

ninput_fifo_enable \<= pinput_fifo_enable;

nfifoempty \<= fifoempty;

nroad_write \<= road_write;

nlast_road \<= last_road;

nhits_busy \<= phits_busy;

nroad_event_count \<= proad_event_count;

vroad_event_count \<= \"00000000\";

nz_write \<= pz_write;

nevent_end \<= pevent_end;

case pstate is

when sevent =\>

ncount \<= zero6;

vcount \<= zero6;

nhits_busy \<= \'0\';

loadin \<= \'0\';

ninput_fifo_enable \<= \'0\';

nz_write \<= \'0\';

nevent_end \<= \'0\';

if(event_start = \'1\') then

\-- yes, we have a new event so go to the next state

nstate \<= sfirstload;

nroad_event_count \<= proad_event_count + 1;

> \-- the new internal event count

else

nstate \<= sevent;

end if;

when sfirstload =\> \-- will load the first road into the comparator

if (proad_write = \'1\') then

> \-- do we have a road_write signal only

\-- then this the first road and there are more to come

loadin \<= \'1\';

vcount\<= zero6;

nstate \<= snext;

elsif(plast_road = \'1\') then

\-- do we have no roads and this is the signal of end of roads

nstate \<= slast_road;

else

nstate \<= sfirstload;

> \-- otherwise wait in this state for a road_write signal

end if;

when snext =\>

> \-- checking whether the road_write signal has gone low,

\-- only then can we wait for the next road_write high

if (proad_write =\'0\') then

nstate \<= sload;

loadin \<= \'0\';

else

nstate \<= snext;

end if;

when sload =\> \--loading the next road_data into next comaparator

if (proad_write = \'1\') then

ncount \<= pcount + 1;

vcount \<= pcount + 1;

loadin \<= \'1\';

nstate \<= snext;

elsif (plast_road = \'1\') then

nstate \<= slast_road;

else

nstate \<= sload;

end if;

when slast_road =\> \-- the previous road was the last raod

\-- so now load the centroid

if (pfifoempty = \'0\') then

ninput_fifo_enable \<= \'1\';

nhits_busy \<= \'1\';

vroad_event_count \<= proad_event_count - 1;

> \-- storing the current event value

nstate \<= sdecide;

else

nstate \<= slast_road;

end if;

when sdecide =\>

ninput_fifo_enable \<= \'0\';

if (datatype(1 downto 0) = \"10\") then \-- if the centroid is axial

mux_select \<= \'0\';

nstate \<= scomp_read;

elsif(datatype(1 downto 0) = \"11\") then

\-- if the centroid is z-axis

mux_select \<= \'1\';

nstate \<= scentroid_write;

nz_write \<= \'1\';

else

nstate \<= slast_road;

end if;

when scentroid_write =\>

\-- this state writes the z-centroid in the block to be formatted

\-- and written to the fifo

nz_write \<= \'1\';

nstate \<= slast_road;

when scomp_read =\>

\-- now the comaparator output is read to be read in the

\-- hit register to get valid hits

nread_comp \<= \'1\'; \-- active high signal

nstate \<= shitreg_read;

when shitreg_read =\>

nread_hitreg \<= \'1\';

nread_comp \<= \'0\';

nstate \<= swait;

when swait =\>

\-- wait till the hits for the centroid are found and put in the data
format

nread_hitreg \<= \'0\';

if (pdone =\'1\') then

\-- active high signal from the pointer block

if (pfifoempty = \'0\'and pend_of_event = \'1\') then

\-- indicating it is through with the centroids

nstate \<= sevent;

\-- yes wait for the new event start

nhits_busy \<= \'0\';

\-- the hit filter is not busy, the calculation is done

elsif (pfifoempty = \'1\' and pend_of_event = \'0\') then

\-- no not yet done, but fifo is still being loaded

nstate \<= sdata_wait;

else

nstate \<= slast_road; \-- go pull another centroid

end if;

else

nstate \<= swait;

end if;

when sdata_wait =\> \-- wait for the fifo to go down again

if (pfifoempty = \'0\') then

nstate \<= slast_road;

else

nstate \<= sdata_wait;

end if;

when others =\>

\-- if any other state other than the above defined go to the initial
state

nstate \<= sevent;

end case;

end process;

\-- this process block is to decide whether axial centroids should go to
the comparator

\-- or the zaxis-degree centroids to the fifo

process(pmux_select,pcentroid)

begin

va_centroid_comp \<= zero14;

vz_centroid_fifo \<= zero14;

case mux_select is

when \'0\' =\>

va_centroid_comp \<= pend_of_event & pcentroid;

when \'1\' =\>

vz_centroid_fifo \<= pend_of_event & pcentroid;

when others =\>

va_centroid_comp \<= zero14;

vz_centroid_fifo \<= zero14;

end case;

end process;

\--this block assigns the comparator in which road-data will be loaded

process(loadin,pcount,proad)

variable tcount : unsigned (5 downto 0);

begin

nroad \<= proad;

tcount := vcount + 1;

if(loadin = \'1\') then \-- active low signal

road \<= tcount;

else

road \<= zero6;

end if;

end process;

\-- this block give is out the final mask to be used to determine the
hits

process(pread_comp,pmask)

variable tmask : unsigned (5 downto 0);

begin

tmask := pcount + 1;

nmask \<= pmask;

if(pread_comp = \'1\') then

mask \<=tmask;

else

mask \<= zero6;

end if;

end process;

\-- process block to register the signals

process(clock,reset,nstate,ncount,nread_comp,ndone,nfifoempty,nroad_write,

nlast_road,nhits_busy,nroad,nmask,nroad_event_count,ncentroid,nevent_end)

begin

if (reset =\'0\') then

pstate \<= sevent;

pcount \<= zero6;

pmask \<= zero6;

proad \<= zero6;

pread_comp \<= \'0\';

pread_hitreg \<= \'0\';

pdone \<= \'0\';

pfifoempty \<= \'0\';

proad_write \<= \'0\';

plast_road \<= \'0\';

phits_busy \<= \'0\';

proad_event_count \<= \"00000000\";

pcentroid \<= zero13;

pevent_end \<= \'0\';

pend_of_event \<= \'0\';

elsif( clock\'event and clock=\'1\') then

pstate \<= nstate;

pcount \<= ncount;

pmask \<= nmask;

proad \<= nroad;

pread_comp \<= nread_comp;

pread_hitreg \<= nread_hitreg;

pdone \<= ndone;

pfifoempty \<= nfifoempty;

proad_write \<= nroad_write;

plast_road \<= nlast_road;

phits_busy \<= nhits_busy;

proad_event_count \<= nroad_event_count;

pcentroid \<= ncentroid;

pevent_end \<= nevent_end;

pend_of_event \<= nend_of_event;

end if;

end process;

\-- block to register the centroid fifo enable signal

process( clock,reset,ninput_fifo_enable,nz_write)

begin

if (reset =\'0\') then

pinput_fifo_enable \<= \'0\';

pz_write \<= \'0\';

elsif( clock\'event and clock=\'0\') then

pinput_fifo_enable \<= ninput_fifo_enable;

pz_write \<= nz_write;

end if;

end process;

\-- assignment of all output signals

read_comp \<= pread_comp;

read_hitreg \<= pread_hitreg;

count \<= pcount;

input_fifo_enable \<= pinput_fifo_enable;

hits_busy \<= phits_busy;

road_event_count \<= vroad_event_count;

a_centroid_comp \<= va_centroid_comp;

z_centroid_fifo \<= vz_centroid_fifo;

z_write \<= pz_write;

end architecture behavior;

## C.19: Z-CENTROID  {#c.19-z-centroid .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--File:z_centroid.vhd

\-- To put the z centroids in the right format and then give them to L3

\-- and also store them in a FIFO within the design

\-- Originally created by : Shweta Lolage : Date 06/29/2000

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- The initialization of the standard libraries

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- Entity Declaration

entity z_centroid is

port (clock,reset : in std_logic;

zvc_enable : in std_logic;

\-- this signal indicates whether the data should be written to the
fifo\'s

z_centroid : in unsigned (13 downto 0);

\-- the z- axis centroid tagged with the end of event on the MSB

z_write : in std_logic;

\-- write signal from the control indicating the centroid coming in

\-- is z axis-type

l3_trailer : in unsigned (31 downto 0);

\-- this trailer is passed on from the centroid finder block

pulse_area : in unsigned (1 downto 0);

\-- from the centroid finder output FIFO

z_l3_output : out unsigned (31 downto 0);

\-- the output which is passed on to the L3 buffer

z_enable : out std_logic

);

end entity z_centroid;

\-- Architecture Body

architecture behavior of z_centroid is

\-- internal signals for the process blocks

signal nz_l3_output,pz_l3_output : unsigned (31 downto 0);

signal nz_enable,pz_enable : std_logic;

signal nl3_trailer,pl3_trailer : unsigned (31 downto 0);

signal pevent_status,nevent_status : std_logic;

signal pcentroid,ncentroid : unsigned(12 downto 0);

signal ppulse_area, npulse_area : unsigned (1 downto 0);

constant c_type : unsigned (1 downto 0) := \"11\";

constant zero2 : unsigned (1 downto 0) := \"00\";

constant zero4 : unsigned (3 downto 0) := \"0000\";

constant zero5 : unsigned (4 downto 0) := \"00000\";

constant zero11 : unsigned (10 downto 0) := \"00000000000\";

constant zero13 : unsigned (12 downto 0) := \"0000000000000\";

constant zero14 : unsigned (13 downto 0) := \"00000000000000\";

constant zero17 : unsigned (16 downto 0) := \"00000000000000000\";

constant zero32 : unsigned (31 downto 0) :=
\"00000000000000000000000000000000\";

begin

nl3_trailer \<= l3_trailer;

nevent_status \<= z_centroid(13);

ncentroid \<= z_centroid (12 downto 0);

npulse_area \<= pulse_area;

process(zvc_enable,z_write)

begin

nz_l3_output \<= pz_l3_output;

if (zvc_enable = \'1\' and z_write = \'1\') then

nz_enable \<= \'1\';

if (pevent_status = \'0\') then

nz_l3_output \<= \"0\" & pl3_trailer(21 downto 19) & c_type &
ppulse_area & pl3_trailer(18 downto 8) & pcentroid;

else

nz_l3_output \<= pl3_trailer;

end if;

else

nz_enable \<= \'0\';

end if;

end process;

\-- this process block is to register the signals

process( reset,clock,nz_l3_output,nz_enable)

begin

if(reset =\'0\') then

pz_l3_output \<= zero32;

pl3_trailer \<= zero32;

pcentroid \<= zero13;

ppulse_area \<= zero2;

pevent_status \<= \'0\';

pz_enable \<= \'0\';

elsif (clock\'event and clock =\'1\') then

pz_l3_output \<= nz_l3_output;

pl3_trailer \<= nl3_trailer;

pcentroid \<= ncentroid;

ppulse_area \<= npulse_area;

pevent_status \<= nevent_status;

pz_enable \<= nz_enable;

end if;

end process;

\-- assignment of the output signals

z_l3_output \<= pz_l3_output;

z_enable \<= pz_enable;

end architecture behavior;

## C.20: COMPARATOR {#c.20-comparator .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\--File:comparator.vhd

\-- To compare the strip pointer with the data value from the

\-- road data

\-- Originally created by : Shweta Lolage

\--Modified by Shweta Lolage on 05/15/2000 : Changes made according to
the new approach

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-- Entity Declaration

entity comparator is

port (clock,reset : in std_logic;

centroid : in unsigned (10 downto 0);

\-- the centroid value of out of the centroid finder

uroaddata : in unsigned (10 downto 0); \-- the upper road_data address

lroaddata : in unsigned (10 downto 0); \-- the lower road)data address

loadroad: in std_logic;

\-- load the road data at the inputs into the comparator

hit : out std_logic \-- to give outthe comparator output

);

end entity comparator;

\-- Architecture Body

architecture behavior of comparator is

\-- internal signals for the process blocks

signal ndata,pdata, compare1, compare2 : std_logic;

signal nroaddatau,proaddatau,nroaddatal,proaddatal : unsigned (10 downto
0);

constant zero11 : unsigned ( 10 downto 0) := \"00000000000\";

begin

\-- this process block loads in the upper and lower road-data in the
comparator

process(loadroad,uroaddata,lroaddata)

begin

if (loadroad = \'1\') then

nroaddatal \<= lroaddata;

nroaddatau \<= uroaddata;

else

nroaddatal \<= proaddatal;

nroaddatau \<= proaddatau;

end if;

end process;

\-- this block is used for the comparison of the road-data

\-- with the given centroid

process(proaddatau,proaddatal,centroid)

begin

compare1 \<= \'0\';

compare2 \<= \'0\';

if( proaddatau /= zero11 and centroid /= zero11 ) then

if (proaddatau \>= centroid ) then

compare1 \<= \'1\';

else

compare1 \<= \'0\';

end if;

else

compare1 \<= \'0\';

end if;

if(proaddatal /= zero11 and centroid /= zero11) then

if (proaddatal \<= centroid) then

compare2 \<= \'1\';

else

compare2 \<= \'0\';

end if;

else

compare2 \<= \'0\';

end if;

end process;

\-- this block gives the result of the comparison

process (compare1,compare2)

begin

ndata \<= pdata;

if (compare1 =\'1\' and compare2 =\'1\') then

ndata \<= \'1\';

else

ndata \<= \'0\';

end if;

end process;

\-- the process block to register the road-data signals

process( nroaddatau,nroaddatal,ndata,clock,reset)

begin

if ( reset =\'0\') then

proaddatau \<= zero11;

proaddatal \<= zero11;

pdata \<= \'0\';

elsif ( clock\'event and clock=\'1\') then

proaddatau \<= nroaddatau;

proaddatal \<= nroaddatal;

pdata \<= ndata;

end if;

end process;

\-- final out from the comparator

hit \<= pdata;

end architecture behavior;

## C.21: HIT REGISTER {#c.21-hit-register .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- File:r2_hitreg_v2.vhd

\-- this process block finds the valid hits

\-- Originally created by : Shweta Lolage

\-- By Shweta Lolage on 05/17/2000 : Changes made according to the new
approach

\--modified on 06/04 /2000 : by Shweta Lolage

\-- modified to remove the delays

\-- The control output line removed from this block and put in the
control logic as an additional state

\-- date - 09/04/2000 - Shweta Lolage

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-- Entity Declaration

entity hitreg is

port (clock, reset : in std_logic;

read_comp : in std_logic; \-- read signal from the control block

mask,hitreg : in unsigned (45 downto 0);

\-- the mask register and the hit register used to find the valid hits

hitbit : out std_logic_vector (45 downto 0) \-- valid hits

);

end entity hitreg;

\-- Architecture Body

architecture behavior of hitreg is

signal nhitbit, phitbit : std_logic_vector (45 downto 0);

constant zero46 : std_logic_vector (45 downto 0) :=
\"0000000000000000000000000000000000000000000000\";

begin

\-- process block to register in the mask and the hits register

process (mask,hitreg)

begin

if (read_comp = \'1\') then

nhitbit(0) \<= mask(0) and hitreg(0);

nhitbit(1) \<= mask(1) and hitreg(1);

nhitbit(2) \<= mask(2) and hitreg(2);

nhitbit(3) \<= mask(3) and hitreg(3);

nhitbit(4) \<= mask(4) and hitreg(4);

nhitbit(5) \<= mask(5) and hitreg(5);

nhitbit(6) \<= mask(6) and hitreg(6);

nhitbit(7) \<= mask(7) and hitreg(7);

nhitbit(8) \<= mask(8) and hitreg(8);

nhitbit(9) \<= mask(9) and hitreg(9);

nhitbit(10) \<= mask(10) and hitreg(10);

nhitbit(11) \<= mask(11) and hitreg(11);

nhitbit(12) \<= mask(12) and hitreg(12);

nhitbit(13) \<= mask(13) and hitreg(13);

nhitbit(14) \<= mask(14) and hitreg(14);

nhitbit(15) \<= mask(15) and hitreg(15);

nhitbit(16) \<= mask(16) and hitreg(16);

nhitbit(17) \<= mask(17) and hitreg(17);

nhitbit(18) \<= mask(18) and hitreg(18);

nhitbit(19) \<= mask(19) and hitreg(19);

nhitbit(20) \<= mask(20) and hitreg(20);

nhitbit(21) \<= mask(21) and hitreg(21);

nhitbit(22) \<= mask(22) and hitreg(22);

nhitbit(23) \<= mask(23) and hitreg(23);

nhitbit(24) \<= mask(24) and hitreg(24);

nhitbit(25) \<= mask(25) and hitreg(25);

nhitbit(26) \<= mask(26) and hitreg(26);

nhitbit(27) \<= mask(27) and hitreg(27);

nhitbit(28) \<= mask(28) and hitreg(28);

nhitbit(29) \<= mask(29) and hitreg(29);

nhitbit(30) \<= mask(30) and hitreg(30);

nhitbit(31) \<= mask(31) and hitreg(31);

nhitbit(32) \<= mask(32) and hitreg(32);

nhitbit(33) \<= mask(33) and hitreg(33);

nhitbit(34) \<= mask(34) and hitreg(34);

nhitbit(35) \<= mask(35) and hitreg(35);

nhitbit(36) \<= mask(36) and hitreg(36);

nhitbit(37) \<= mask(37) and hitreg(37);

nhitbit(38) \<= mask(38) and hitreg(38);

nhitbit(39) \<= mask(39) and hitreg(39);

nhitbit(40) \<= mask(40) and hitreg(40);

nhitbit(41) \<= mask(41) and hitreg(41);

nhitbit(42) \<= mask(42) and hitreg(42);

nhitbit(43) \<= mask(43) and hitreg(43);

nhitbit(44) \<= mask(44) and hitreg(44);

nhitbit(45) \<= mask(45) and hitreg(45);

else

nhitbit \<= zero46;

end if;

end process;

\-- process block to register the signals

process(clock,reset,nhitbit)

begin

if ( reset = \'0\') then

phitbit \<= zero46;

elsif ( clock\'event and clock =\'1\') then

phitbit \<= nhitbit;

end if;

end process;

\-- assigning the outputs

hitbit \<= phitbit;

end architecture;

## C.22: HIT FORMAT {#c.22-hit-format .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- File:hit_format.vhd

\-- Process block to locate the hits from the valid hits register

\-- and give them to the format block to put them in the data format

\-- Originally created by : Shweta Lolage

\-- By Shweta Lolage on 05/17/2000 : Changes made according to the new
approach

\-- Changes are made to the design to combine the hit block and the
format block

\-- date : 09/04/2000 - Shweta Lolage

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-- Entity Declaration

entity hit_format is

port (clock,reset : in std_logic;

count : in unsigned (5 downto 0);

\-- upper limit for the hit search as this is the number of comparators

\-- loaded with valid road_data

hitreg: in std_logic_vector (45 downto 0);

> \-- valid hits register

l3_trailer : in unsigned (31 downto 0) ;

\-- this trailer is passed on from the centroid finder block

pulsearea : in unsigned (1 downto 0); \-- pulse_area for the centroid

centroid : in unsigned (13 downto 0); \-- centroid which is compared

hitreg_valid : in std_logic; \-- read valid hit register signal

cen_done,hits_done : out std_logic;

> \--cen_done signal for the channel control block

output : out unsigned (32 downto 0);

> \-- the final output to the hits FIFO

fifo_enable,end_of_event : out std_logic

> \-- signal to the main control block indicating that the \--
>
> \-- channel has valid hits

);

end entity hit_format;

\-- Architecture Body

architecture behavior of hit_format is

type hitstates is
(sinit,spoint_select,sready,sread_hits,sread_bit,swrite_hit,

> soutput_hit,snext_hit,strailer);

signal pstate,nstate : hitstates;

signal or1,or2,or3,or4,or5 : std_logic;

signal nor1,nor2,nor3,nor4,nor5 : std_logic;

signal por1,por2,por3,por4,por5 : std_logic;

signal nhits_present,phits_present,pcen_done,ncen_done : std_logic;

signal npointer,ppointer: unsigned (5 downto 0);

signal ncounter,pcounter: unsigned (5 downto 0);

signal nhitreg_valid,phitreg_valid : std_logic;

signal nhitreg, phitreg : std_logic_vector(45 downto 0);

signal nhits_done,phits_done,nbit,pbit : std_logic;

constant zero46 : std_logic_vector (45 downto 0) :=
\"0000000000000000000000000000000000000000000000\";

signal ndata,pdata: unsigned (32 downto 0);

signal ncount,pcount : unsigned (5 downto 0);

signal noutput,poutput : unsigned (32 downto 0);

signal nfifoenable,pfifoenable : std_logic;

signal npulsearea,ppulsearea : unsigned (1 downto 0);

signal pcentroid, ncentroid : unsigned (12 downto 0);

signal nevent_status, pevent_status : std_logic;

signal nl3_trailer,pl3_trailer : unsigned (31 downto 0);

constant zero33 : unsigned (32 downto 0) :=
\"000000000000000000000000000000000\";

constant zero32 : unsigned (31 downto 0) :=
\"00000000000000000000000000000000\";

constant zero22 : unsigned (21 downto 0) := \"0000000000000000000000\";

constant zero17 : unsigned (16 downto 0) := \"00000000000000000\";

constant zero16 : unsigned (15 downto 0) := \"0000000000000000\";

constant zero11 : unsigned (10 downto 0) := \"00000000000\";

constant zero8 : unsigned (7 downto 0) := \"00000000\";

constant zero6 : unsigned (5 downto 0) := \"000000\";

constant zero3 : unsigned (2 downto 0) := \"000\";

constant two : unsigned (1 downto 0) := \"10\";

constant three : unsigned (1 downto 0) := \"11\";

begin

\-- the initialization of the signals

npulsearea \<= pulsearea;

ncentroid \<= centroid(12 downto 0);

nevent_status \<= centroid(13);

\-- the bit tagged along with centroid indicating the end of event

nl3_trailer \<= l3_trailer;

nhitreg_valid \<= hitreg_valid;

\-- this process block groups the comparators to reduce the search

process(hitreg)

variable tor1,tor2,tor3,tor4,tor5 : std_logic;

begin

tor1 := \'0\';

tor2 := \'0\';

tor3 := \'0\';

tor4 := \'0\';

tor5 := \'0\';

for i in 0 to 9 loop

tor1 := tor1 or hitreg(i);

end loop;

or1 \<= tor1;

for i in 10 to 19 loop

tor2 := tor2 or hitreg(i);

end loop;

or2 \<= tor2;

for i in 20 to 29 loop

tor3 := tor3 or hitreg(i);

end loop;

or3 \<= tor3;

for i in 30 to 39 loop

tor4 := tor4 or hitreg(i);

end loop;

or4 \<= tor4;

for i in 40 to 45 loop

tor5 := tor5 or hitreg(i);

end loop;

or5 \<= tor5;

end process;

\-- this process block is to find the hits and send them to the format
block

process(ppointer,hitreg_valid,count,pcen_done,pcen_done,pcounter)

begin

ncen_done \<= pcen_done;

ncounter \<= pcounter;

nor1 \<= por1;

nor2 \<= por2;

nor3 \<= por3;

nor4 \<= por4;

nor5 \<= por5;

nhits_present \<= phits_present;

npointer \<= ppointer;

nhitreg \<= phitreg;

nfifoenable \<= pfifoenable;

noutput \<= poutput;

nhits_done \<= phits_done;

case pstate is

when sinit =\> \-- initial state,

ncen_done \<= \'0\';

nhits_present \<= \'0\';

nfifoenable \<= \'0\';

nhits_done \<= \'0\';

if (hitreg_valid =\'1\') then \-- is valid register ready to be read

nstate \<= spoint_select;

> \-- yes, go ahead and select the point of start

\-- after determining whether we have any hits

nhitreg \<= hitreg;

nor1 \<= or1;

nor2 \<= or2;

nor3 \<= or3;

nor4 \<= or4;

nor5 \<= or5;

else

nstate \<= sinit;

\-- no be in this state and wait for it

nhitreg \<= zero46;

nor1 \<=\'0\';

nor2 \<=\'0\';

nor3 \<=\'0\';

nor4 \<=\'0\';

nor5 \<=\'0\';

end if;

when spoint_select =\>

nfifoenable \<= \'0\';

nhits_present \<= por1 or por2 or por3 or por4 or por5;

if (por1 =\'1\') then

npointer \<= \"000000\";

else

if (por2 =\'1\') then

npointer \<= \"001010\";

else

if (por3 =\'1\') then

npointer \<= \"010100\";

else

if (por4=\'1\') then

npointer \<= \"011110\";

else

if (por5 = \'1\') then

npointer \<= \"101000\";

else

npointer \<= \"000000\";

end if;

end if;

end if;

end if;

end if;

nstate \<= sready;

when sready =\> \-- read the valid hits

nfifoenable \<= \'0\';

if (phits_present = \'1\') then \-- are there any hits in this register

nstate \<= sread_hits; \-- yes there are

ncen_done \<= \'0\';

ncounter \<= ppointer;

else

ncen_done \<= \'1\';

nstate \<= sinit;

end if;

when sread_hits =\>

nstate \<= sread_bit;

nfifoenable \<= \'0\';

case pcounter is

when \"000000\" =\> nbit \<= phitreg(0);

when \"000001\" =\> nbit \<= phitreg(1);

when \"000010\" =\> nbit \<= phitreg(2);

when \"000011\" =\> nbit \<= phitreg(3);

when \"000100\" =\> nbit \<= phitreg(4);

when \"000101\" =\> nbit \<= phitreg(5);

when \"000110\" =\> nbit \<= phitreg(6);

when \"000111\" =\> nbit \<= phitreg(7);

when \"001000\" =\> nbit \<= phitreg(8);

when \"001001\" =\> nbit \<= phitreg(9);

when \"001010\" =\> nbit \<= phitreg(10);

when \"001011\" =\> nbit \<= phitreg(11);

when \"001100\" =\> nbit \<= phitreg(12);

when \"001101\" =\> nbit \<= phitreg(13);

when \"001110\" =\> nbit \<= phitreg(14);

when \"001111\" =\> nbit \<= phitreg(15);

when \"010000\" =\> nbit \<= phitreg(16);

when \"010001\" =\> nbit \<= phitreg(17);

when \"010010\" =\> nbit \<= phitreg(18);

when \"010011\" =\> nbit \<= phitreg(19);

when \"010100\" =\> nbit \<= phitreg(20);

when \"010101\" =\> nbit \<= phitreg(21);

when \"010110\" =\> nbit \<= phitreg(22);

when \"010111\" =\> nbit \<= phitreg(23);

when \"011000\" =\> nbit \<= phitreg(24);

when \"011001\" =\> nbit \<= phitreg(25);

when \"011010\" =\> nbit \<= phitreg(26);

when \"011011\" =\> nbit \<= phitreg(27);

when \"011100\" =\> nbit \<= phitreg(28);

when \"011101\" =\> nbit \<= phitreg(29);

when \"011110\" =\> nbit \<= phitreg(30);

when \"011111\" =\> nbit \<= phitreg(31);

when \"100000\" =\> nbit \<= phitreg(32);

when \"100001\" =\> nbit \<= phitreg(33);

when \"100010\" =\> nbit \<= phitreg(34);

when \"100011\" =\> nbit \<= phitreg(35);

when \"100100\" =\> nbit \<= phitreg(36);

when \"100101\" =\> nbit \<= phitreg(37);

when \"100110\" =\> nbit \<= phitreg(38);

when \"100111\" =\> nbit \<= phitreg(39);

when \"101000\" =\> nbit \<= phitreg(40);

when \"101001\" =\> nbit \<= phitreg(41);

when \"101010\" =\> nbit \<= phitreg(42);

when \"101011\" =\> nbit \<= phitreg(43);

when \"101100\" =\> nbit \<= phitreg(44);

when \"101101\" =\> nbit \<= phitreg(45);

when others =\> nbit \<= \'0\';

end case;

when sread_bit =\>

nfifoenable \<= \'0\';

if (pbit = \'1\') then \-- no there are more

nstate \<= swrite_hit;

ncount \<= pcounter;

else

nstate \<= snext_hit;

ncount \<= pcount;

end if;

when swrite_hit =\>

nstate \<= soutput_hit;

nfifoenable \<= \'0\';

ndata(32) \<= \'0\';

ndata(31 downto 26) \<= pcount;

ndata(25 downto 24) \<= ppulsearea;

ndata(23 downto 13) \<= pl3_trailer(18 downto 8);

ndata(12 downto 0) \<= pcentroid;

when soutput_hit =\>

nstate \<= snext_hit;

noutput\<= pdata;

nfifoenable \<= \'1\';

when snext_hit =\>

\-- state to decide whether we should go ahead for the next hit

nfifoenable \<= \'0\';

if (pcounter \<= count) then

\-- have we reached the end of the comparators

ncen_done \<=\'0\';

ncounter \<= pcounter + 1; \-- No , the end has not yet come

nstate \<= sread_hits;

else

ncen_done \<= \'1\';

ncounter \<= \"000000\";

if (pevent_status = \'0\')then

nstate \<= sinit;

\-- yes go to start and wait for the next lot

else

nstate \<= strailer;

nhits_done \<= \'1\';

ndata (32) \<= \'1\';

ndata(31 downto 0) \<= pl3_trailer;

end if;

end if;

when strailer =\>

nstate \<= sinit;

nfifoenable \<= \'1\';

noutput \<= pdata;

nhits_done \<= \'0\';

when others =\>

\-- any other state other than the once defined above, go to the initial
state

nstate \<= sinit;

ncen_done \<= \'0\';

nhits_done \<= \'0\';

end case;

end process;

\--this process block registers the signals

process(clock,reset)

begin

if (reset =\'0\') then

ppointer \<=\"000000\";

pcounter \<=\"000000\";

phits_present \<= \'0\';

pstate \<= sinit;

pcen_done \<= \'0\';

pbit \<= \'0\';

phitreg_valid \<= \'0\';

por1 \<= \'0\';

por2 \<= \'0\';

por3 \<= \'0\';

por4 \<= \'0\';

por5 \<= \'0\';

phitreg \<= zero46;

elsif (clock\'event and clock =\'1\') then

ppointer \<= npointer;

pcounter \<= ncounter;

phits_present \<= nhits_present;

pstate \<= nstate;

pcen_done \<= ncen_done;

pbit \<= nbit;

phitreg_valid \<= nhitreg_valid;

por1 \<= nor1;

por2 \<= nor2;

por3 \<= nor3;

por4 \<= nor4;

por5 \<= nor5;

phitreg \<= nhitreg;

end if;

end process;

\-- the process block to register the signals

process(clock,reset)

begin

if(reset =\'0\') then

poutput \<= zero33;

pcount \<= zero6;

pdata \<= zero33;

ppulsearea \<= \"00\";

pcentroid \<= \"0000000000000\";

pevent_status \<= \'0\';

pl3_trailer \<= zero32;

pfifoenable \<= \'0\';

phits_done \<= \'0\';

elsif( clock\'event and clock=\'1\') then

poutput \<= noutput;

pcount \<= ncount;

pdata \<= ndata;

ppulsearea \<= npulsearea;

pcentroid \<= ncentroid;

pl3_trailer \<= nl3_trailer;

pevent_status \<= nevent_status;

pfifoenable \<= nfifoenable;

phits_done \<= nhits_done;

end if;

end process;

\-- final out to the fifo, this block is not totally complete as will
have to see the handshaking with the fifo

output \<= poutput;

fifo_enable \<= pfifoenable;

end_of_event \<= poutput(32);

cen_done \<= pcen_done;

hits_done \<= phits_done;

end architecture;

## C.23: HIT READ OUT {#c.23-hit-read-out .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- File:hit_readout.vhd

\-- Process block to read the hits from the FIFO by the control block

\-- Originally created by : Shweta Lolage :08/01/2000

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-- Entity Declaration

entity hit_readout is

port (clock, reset : in std_logic;

hits_enable,hit_fifo_empty, hits_busy : in std_logic;

read_hit_fifo,hits_available : out std_logic

);

end entity hit_readout;

\-- Architecture Body

architecture behavior of hit_readout is

signal nread_hit_fifo,pread_hit_fifo : std_logic;

begin

process( hits_enable, hit_fifo_empty)

begin

if(hits_enable = \'1\' and hit_fifo_empty = \'0\') then

nread_hit_fifo \<= \'1\'; \-- this is read_req signal to the fifo

else

nread_hit_fifo \<= \'0\';

end if;

end process;

hits_available \<= hits_busy;

\-- this is an internal signal to the read_out control to indicate that
hits are being processed

reg : process ( clock, reset)

begin

if(reset = \'0\') then

pread_hit_fifo \<= \'0\';

elsif (clock\'event and clock =\'1\') then

pread_hit_fifo \<= nread_hit_fifo;

end if;

end process reg;

\-- assigning the outputs

read_hit_fifo \<= pread_hit_fifo;

end architecture;

## C.24: TRAILER PATTERN RECOGINSER {#c.24-trailer-pattern-recoginser .unnumbered}

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

\-- File:trailer_pat.vhd

\-- Process block to check for the trailer

\-- Originally created by : Shweta Lolage :08/01/2000

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

library altera;

use altera.maxplus2.all;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

\-- Entity Declaration

entity trailer_pat is

port (stream : in unsigned(4 downto 0);

trailer_signal : out std_logic

);

end entity trailer_pat;

\-- Architecture Body

architecture behavior of trailer_pat is

constant pattern : unsigned (4 downto 0):= \"11110\";

begin

with stream select

trailer_signal \<= \'1\' when pattern,

\'0\' when others;

end architecture;

C.25 DETAILED MEMORY ALLOCATION OF THE DOWNLOADED PARAMETERS

1.  Monitor space: 1K memory: 0000 -- 03FF.

2.  Miscellaneous: 1K memory: 0400 -- 07FF.

3.  Gain Offset LUT: 4K X 8: 0800 -- 17FF

4.  Test data LUT: 1K (default) X 18: 1800 -- 1BFF.

5.  Empty Space: 1C00 -- 3FFF.

6.  Road data LUT: 16 K X 22: 4000 -- 7FFF.

### 

### C.25.1 The monitoring data memory allocation

1.  SERR,mismatch,SMT_ID,SEQ_ID,HDI_ID,data (last data word read):

> address 0000.

2.  SERR error count : address 0001.

3.  Mismatch counter: mismatch in the SEQ-ID or the HDI-ID: address
    0002.

4.  Zero error count: Zero byte not found: address 0003.

5.  Number of undefined data_type clusters: address 0010.

6.  Number of axial data_type clusters: address 0011.

7.  Number of stereo data_type clusters: address 0012.

8.  Number of Z-axis data_type clusters: address 0013.

9.  Data activity on Chip(I): address 0020-0028.

### C.25.2 The miscellaneous memory space memory allocation

1.  Bad channel: 32 X 64: address: 0400 -- 047F.

2.  Chip ranges: 24 X 1: address: 0480.

3.  Pulse area thresholds: 24 X 4 X4: address: 0500 -- 0503.

4.  Miscellaneous parameters: 32 X 1: address: 0580.

5.  Cluster threshold values: 17 X 4: address: 0600 -- 0603.