"$Id: pld5.src,v 1.20 2001/12/21 16:18:40 warren Exp $
"==============================================================================
#TITLE	 'ATLAS SCT	TIM, PLD5: Serialiser &	FIFO Control';
#ENGINEER 'Martin	Postranecky	/ Dominic A	Hayes';
#COMPANY	 'University College	London';
#COMMENT	 '';
"==============================================================================
"$Log: pld5.src,v $
"Revision 1.20  2001/12/21 16:18:40  warren
"Reworked TT logic to match ID
"
"Revision 1.19  2001/12/20 11:03:49  warren
"Added L1_strobe OR BC_strobe in /runmode only
"
"Revision 1.18  2001/12/19 19:42:32  warren
"Changed IDen timing to use IDclk
"
"Revision 1.17  2001/12/18 13:52:44  warren
"Reworked FIFO - now much more syncronous - only used posi clk
"
"Revision 1.16  2001/11/27 16:48:21  warren
"changed version to 4 (for tag nik4)
"
"Revision 1.15  2001/11/16 15:05:38  warren
"Added software rev ID 3 (CAM3)
"
"Revision 1.14  2001/09/14 15:56:07  warren
"Better clocking all round + TT now same as ID
"
"Revision 1.13  2001/09/07 17:28:43  warren
"fixed async fifo en timing -- works!
"
"Revision 1.12  2001/08/30 12:20:45  warren
"Tidied, Capitalization
"
"Revision 1.11  2001/08/08 18:41:49  warren
"Improved clocking in ID serialiser etc, new stm
"and signal names case names
"
"Revision 1.10  2001/07/23 11:18:40  warren
"renamed signals with proper polarity n prefixes and removed LOW_TRUEs
"
"Revision 1.9  2001/07/19 10:44:56  warren
"removed unused spare bus lines
"
"Revision 1.8  2001/07/16 13:13:31  warren
"*** empty log message ***
"
"Revision	1.7  2001/04/03 15:44:54  warren	
"Added, but	needed to disable	(for now) new reg	34	"




"==============================================================================
"MODS
"----
"22mar00	name:	reg_fifo_state	--> reg0e
"23mar00	db[15..0] --> db[7..0]:	1/2 of reg0e, the	other	1/2 on pld6.
"06apr00	IDaf and	TTaf i/p	added.
"19may00	name:	fs[1..0]	->	fs1, fs0.
"			vfiforeset removed.
"23may00	reg0E	byte swapped to high	to	reflect actual	definition
"24may00	ID_strobe now NODE, new	i/ps BC/L1_strobe. s4_5	->	s4b_5.
"05jun00	ID_strobe self	sync reset by move to State IDopen_portA.
"06jun00	input	RunMode added.	NC	at	moment.
"08jun00	name:	bufFERclk_in -> clk5.
"22jun00	TT/ID_stop state added to guarentee	stop bit	before data_sent asserted
"				(may be unnecessary as it effectively generates	a second	stop bit).
"21jul00	bWriteb and	nLEb2 added (not used)
"14sep00	dbhoe	->	dboe and	/bReadb -> bReadb.
"02Nov00	Implimeted FIFO counts uses enA for	up, and enB	for down	(untested)
"15Feb01	reg22pld5 no longer LOW_TRUE jbl, mrmw
"16Feb01	changed reg22 ro reg32
"20Mar01	Checked that nOA_rst	was correct	polarity
"			Added	reg34	- for	IRQ Stat/ID	- used ex-s1_5[6]	as	reg line	from pld1
"21Mar01	Cleaned up nOA_rst legibity (added OA_rst	= /nOA_rst)
"08Aug01	Added clocking to ID_Strobe and StrobeReset
"			Reworked L1ID, BCID register clocking and assos. logic
"07Sep01 Added clocking to signals IDenA, IDenB on /clk5
"			ID loading is now done on /IDenA
"14Sep01 Applied all the ID changes to TT
"15Nov01 Changed serial number to 3 for rel CAM3
"27Nov01 Changed serial number to 4 for rel NIK4
"17Dec01 Reworked FIFO timing for on the PORTA side - discarded state-machine
"18Dec01 Reworked FIFO timing for on the PORTB side - discarded state-machine
"        Changed serial number to 5 for rel NIK5
"20Dec01 Changed BC_Strobe AND L1_Strobe in /runmode
"21Dec01 Fixed up TT timing to match L1ID


"==============================================================================
INPUT		nOA_rst;
NODE		OA_rst;
			OA_rst =	/nOA_rst;


INPUT		RunMode;

INPUT		clk5;


INPUT		Reg0E,
			bReadb,
			bWriteb,
			nLEb2;

													 
"*** what is this?
OUTPUT	fs1, fs0;													 
			fs1 =	0;
			fs0 =	0;

"-------------------------------------------------------------------------------
"FIFO Reset
"-------------------------------------------------------------------------------
" ensures that	FIFO resets	are asserted for at least 4 clka/clkb cycles
"							after	a OA_rst	condition.

OUTPUT	nFIFO_rst;


			STATE_MACHINE machine_fifo_reset
				CLOCKED_BY clk5
				RESET_BY	OA_rst;
			
				STATE	reset0:
					nFIFO_rst =	0;						"rst asserted.
					GOTO reset1;
			
				STATE	reset1:
					nFIFO_rst =	0;						"rst asserted.
					GOTO reset2;
			
				STATE	reset2:
					nFIFO_rst =	0;						"rst asserted.
					GOTO reset3;
			
				STATE	reset3:
					nFIFO_rst =	0;						"rst asserted.
					GOTO fifo_run;
			
				STATE	fifo_run:
					nFIFO_rst =	1 ;					"rst un-asserted.
					GOTO fifo_run ;
			
			END machine_fifo_reset;
			



"==============================================================================

" LEVEL ONE ID

"==============================================================================


"-------------------------------------------------------------------------------
" ID Strobe generation
"---------------------

INPUT		L1_strobe, BC_strobe;

NODE		StrobeReset;

NODE		L1_latch		"Latched L1_strobe:
				CLOCKED_BY L1_strobe	
				RESET_BY	(StrobeReset OR OA_rst);

NODE		BC_latch		"Latched BC_strobe:
				CLOCKED_BY BC_strobe
				RESET_BY	(StrobeReset OR OA_rst);

NODE		qID_strobe
				CLOCKED_BY clk5
				RESET_BY OA_rst;

			L1_latch = 1;
			BC_latch = 1;
			
			qID_strobe = L1_latch AND BC_latch;
						
			StrobeReset = qID_strobe;


"-------------------------------------------------------------------------------
" handles writes to ID FIF0 port	A and	reads	from port B
"--------------------------------------------------------

			
OUTPUT	IDclkA;			
			IDclkA =	clk5;
				
OUTPUT	IDenA 
				CLOCKED_BY IDclkA	
				RESET_BY	OA_rst;

			IDenA = qID_strobe;
		


"Port	B = FIFO	output
"--------------------
"When	data is available	in	the FIFO	(ie, not	empty) nIDef will be HIGH low_true).
"If PLD5	is	ready	(ID_data_busy LOW, not serialising previous FIFO data) it will
"enable the	FIFO clock (IDenB) so that	data will appear on the	FIFO o/p	(where
"it remains	until	the next	IDenB).

OUTPUT	IDclkB;		"generated clks for the	ID	FIFO.
			IDclkB =	clk5;

NODE		L1ID[23..0],
			BCID[11..0]
				CLOCKED_BY ID_load
				RESET_BY	OA_rst;

INPUT		fifo_L1ID_low[11..0],
			fifo_L1ID_high[11..0],
			fifo_BCID[11..0];

			L1ID[11..0]	 =	fifo_L1ID_low[11..0];
			L1ID[23..12] =	fifo_L1ID_high[11..0];	"parallel load the ID reg
			BCID[11..0]	 =	fifo_BCID[11..0];


INPUT		nIDef,
			nIDff,
			nIDae,
			nIDaf;
			

OUTPUT	IDenB			"enables	ports	of	ID	FIFO.
				CLOCKED_BY IDclkB
				RESET_BY	OA_rst;
			

NODE		ID_ser_busy
				DEFAULT_TO 1;


			IDenB = nIDef AND /ID_ser_busy;


"-------------------------------------------------------------------------------
" ID fifo depth counter
"--------------------------
"
" need code	to	keep track of the	FIFO level
"	using	..enA	to	increment, ..enB to dECRement	this IDCounter.

NODE		IDCount[6]
				CLOCKED_BY	clk5
				RESET_BY		OA_rst;
	
			IF IDenA	= 1 THEN				"*** this delays the counter to only have the
				IDCount = IDCount	.+. 1;"*** FIFO level at the next clock. okay?
				
			ELSIF	IDenB	= 1 THEN
				IDCount = IDCount	.-. 1;
				
			ELSE
				IDCount = IDCount;
				
			END IF;
			


"-------------------------------------------------------------------------------
" converts parallel ID data to a	serial stream
"----------------------------------------------

OUTPUT	IDin;	"Actually out to backplane IN

NODE		ID_load
				DEFAULT_TO 0;

			STATE_MACHINE ID_serialiser
				CLOCKED_BY clk5
				RESET_BY	OA_rst;
			
				STATE	ID_idle:	
					IDin = 0	;	
					IF	(IDenB) THEN	
					   ID_ser_busy =	1;	
						GOTO ID_pre_start;
					ELSE
					   ID_ser_busy =	0;
						GOTO ID_idle;
					END IF;
					
				STATE	ID_pre_start: "Delay for data read from fifo
					IDin = 0	;	
				   GOTO ID_start;			

			
				STATE	ID_start:
					ID_load = 1;
					IDin = 1;			"= START BIT.
					GOTO ID0;			
			
				STATE	ID0:
					IDin = L1ID[0];
					GOTO ID1;
			
				STATE	ID1:
					IDin = L1ID[1];
					GOTO ID2;
			
				STATE	ID2:
					IDin = L1ID[2];
					GOTO ID3;
			
				STATE	ID3:
					IDin = L1ID[3];
					GOTO ID4;
			
				STATE	ID4:
					IDin = L1ID[4];
					GOTO ID5;
			
				STATE	ID5:
					IDin = L1ID[5];
					GOTO ID6;
			
				STATE	ID6:
					IDin = L1ID[6];
					GOTO ID7;
			
				STATE	ID7:
					IDin = L1ID[7];
					GOTO ID8;
			
				STATE	ID8:
					IDin = L1ID[8];
					GOTO ID9;
			
				STATE	ID9:
					IDin = L1ID[9];
					GOTO ID10;
			
				STATE	ID10:
					IDin = L1ID[10];
					GOTO ID11;
			
				STATE	ID11:
					IDin = L1ID[11];
					GOTO ID12;
			
				STATE	ID12:
					IDin = L1ID[12];
					GOTO ID13;
			
				STATE	ID13:
					IDin = L1ID[13];
					GOTO ID14;
			
				STATE	ID14:
					IDin = L1ID[14];
					GOTO ID15;
			
				STATE	ID15:
					IDin = L1ID[15];
					GOTO ID16;
			
				STATE	ID16:
					IDin = L1ID[16];
					GOTO ID17;
			
				STATE	ID17:
					IDin = L1ID[17];
					GOTO ID18;
			
				STATE	ID18:
					IDin = L1ID[18];
					GOTO ID19;
			
				STATE	ID19:
					IDin = L1ID[19];
					GOTO ID20;
			
				STATE	ID20:
					IDin = L1ID[20];
					GOTO ID21;
			
				STATE	ID21:
					IDin = L1ID[21];
					GOTO ID22;
			
				STATE	ID22:
					IDin = L1ID[22];
					GOTO ID23;
			
				STATE	ID23:
					IDin = L1ID[23];
					GOTO ID24;
			
				STATE	ID24:
					IDin = BCID[0];
					GOTO ID25;
			
				STATE	ID25:
					IDin = BCID[1];
					GOTO ID26;
			
				STATE	ID26:
					IDin = BCID[2];
					GOTO ID27;
			
				STATE	ID27:
					IDin = BCID[3];
					GOTO ID28;
			
				STATE	ID28:
					IDin = BCID[4];
					GOTO ID29;
			
				STATE	ID29:
					IDin = BCID[5];
					GOTO ID30;
			
				STATE	ID30:
					IDin = BCID[6];
					GOTO ID31;
			
				STATE	ID31:
					IDin = BCID[7];
					GOTO ID32;
			
				STATE	ID32:
					IDin = BCID[8];
					GOTO ID33;
			
				STATE	ID33:
					IDin = BCID[9];
					GOTO ID34;
			
				STATE	ID34:
					IDin = BCID[10];
					GOTO ID35;
			
				STATE	ID35:
					IDin = BCID[11];
					GOTO ID_stop;
			
				STATE	ID_stop:	"may not need to gen.stop bit before ID_ser_busy
					IDin = 0;	"= STOP BIT
					GOTO ID_idle;
			
			END ID_serialiser;


"==============================================================================

" TRIGGER TYPE

"==============================================================================
" handles writes to TT FIF0 port	A and	reads	from port B


"Strobe
"------------------------------------

INPUT		TT_strobe;	 "signal	from TTCrx to validate ID/TT data

NODE		qTT_strobe
				CLOCKED_BY clk5
				RESET_BY OA_rst;
				
			qTT_strobe = TT_strobe;


"Port A
"-------------------------------------

OUTPUT	TTclkA;
			TTclkA =	clk5;

OUTPUT	TTenA
				CLOCKED_BY TTclkA
				RESET_BY	OA_rst;

			TTenA = qTT_Strobe;


"Port B
"------------------------------------

OUTPUT	TTclkb;			"generated clks for the	TT	FIFO.
			TTclkb =	clk5;

INPUT		fifo_TT[9..0];

NODE		TT[9..0]
				CLOCKED_BY TT_load
				RESET_BY	OA_rst;
								
			TT[9..0]	 =	fifo_TT[9..0];

			
INPUT		nTTef,		"empty flag	
			nTTff,		"full flag
			nTTae,		"almost empty
			nTTaf;		"almost full

OUTPUT	TTenB			"enables	ports	of	TT	FIFO.
				CLOCKED_BY TTclkB
				RESET_BY	OA_rst;
				

NODE		TT_ser_busy
				DEFAULT_TO 1;

			TTenB = nTTef AND /TT_ser_busy;
			
"------------------------------------



"-------------------------------------------------------------------------------
" TT FIFO depth counter
"--------------------------
"
" need code	to	keep track of the	FIFO level
"	using	..enA	to	increment, ..enB to dECRement	this IDCounter.

NODE	 	TTCount[6]
				CLOCKED_BY	TTclka
				RESET_BY		OA_rst;
	
			IF TTenA	= 1 THEN
				TTCount = TTCount	.+. 1;
				
			ELSIF	TTenB	= 1 THEN
				TTCount = TTCount	.-. 1;
				
			ELSE
				TTCount = TTCount;
				
			END IF;


"-------------------------------------------------------------------------------
" converts parallel TT data to a	serial stream
"----------------------------------------------

OUTPUT 	TTin;

NODE		TT_load
				DEFAULT_TO 0;

			STATE_MACHINE TT_serialiser
				CLOCKED_BY clk5
				RESET_BY	OA_rst;
			
				STATE	TT_idle:		
					TTin = 0	;		
					IF	(TTenB) THEN	"new TT FIFO data	available.
						TT_ser_busy = 1;
						GOTO TT_pre_start; "TTenB does the parallel load
					ELSE
						TT_ser_busy = 0;
						GOTO TT_idle;
					END IF;

				STATE	TT_pre_start:
					TTin = 0;		
					GOTO TT_start;		

				STATE	TT_start:
					TT_load = 1;
					TTin = 1;						  "=	START	BIT.
					GOTO TT0;						  "goto next bit on next bufFERclk.
			
				STATE	TT0:
					TTin = TT[0];
					GOTO TT1;
			
				STATE	TT1:
					TTin = TT[1];
					GOTO TT2;
			
				STATE	TT2:
					TTin = TT[2];
					GOTO TT3;
			
				STATE	TT3:
					TTin = TT[3];
					GOTO TT4;
			
				STATE	TT4:
					TTin = TT[4];
					GOTO TT5;
			
				STATE	TT5:
					TTin = TT[5];
					GOTO TT6;
			
				STATE	TT6:
					TTin = TT[6];
					GOTO TT7;
			
				STATE	TT7:
					TTin = TT[7];
					GOTO TT8;
			
				STATE	TT8:
					TTin = TT[8];
					GOTO TT9;
			
				STATE	TT9:
					TTin = TT[9];
					GOTO TT_stop;
			
				STATE	TT_stop:		 "may	not need-gens stop bit before TT_ser_busy
					TTin = 0;		 "= STOP BIT
					GOTO TT_idle;
			
			END TT_serialiser;






"-------------------------------------------------------------------------------
" IRQ	Status/ID reg *** under_development
"-------------------

"NODE		IRQ_ID_Register[7..0]
"				CLOCKED_BY nLEb2
"				CLOCK_ENABLED_BY (Reg34	AND bWriteb)
"				RESET_BY	OA_rst
"				DEFAULT_TO 0;

"			IRQ_ID_Register[7..0] =	db_l;




"-------------------------------------------------------------------------------
"VME
"---


BIPUT		db_h[15..8]				"VME databus
				ENABLED_BY dboe_h;
BIPUT		db_l[	7..0]				"VME databus
				ENABLED_BY dboe_l;

NODE		dboe_h;		 			"high-byte	db	output enable.
NODE		dboe_l;		 			"low-byte db output	enable.




INPUT		reg32;
INPUT		reg34;


NODE		Register32[15..8];		"TIM	VERSION ID.	- Read Only	(no clocking)
			Register32[15..8]	= 5;	"### SOFTWARE RELEASE NUMBER OF TIM.
											" NIK5


NODE		fifo_state_register[15..0];
			fifo_state_register[15..0]	= [ /nTTff, /nTTef, TTCount[5..0],
													 /nIDff, /nIDef, IDCount[5..0]	];


			IF	(bReadb)	THEN
				IF	(Reg0E) THEN
					db_h[15..8]	 =	fifo_state_register[15..8];
					db_l[	7..0]	 =	fifo_state_register[7..0];
		
				ELSIF	(Reg32) THEN
					db_h[15..8]	= Register32[15..8];
		
				"ELSIF	(Reg34) THEN
				"	db_l[7..0] = IRQ_ID_Register[7..0];
				"	db_h[15..8]	= 0;
				END IF;
			END IF;
		
		
		
			dboe_h =	bReadb AND (Reg0E	OR	Reg32);	" OR Reg34);
			dboe_l =	bReadb AND (Reg0E);				" OR Reg34);


"------------------------------------------------------------------------------
"SPARE I/O
"---------

INPUT		sgbA[7..0];		 "Spare global	bus A
INPUT		sgbB[7..0];		 "Spare global	bus B
INPUT		sgbC[7..0];		 "Spare global	bus C
INPUT		sgbD[5..0];		 "Spare global	bus D

INPUT		s1_5[5..0];		 "Spare loCAL bus
INPUT		s4b_5[7..0];	 "Spare loCAL bus
INPUT		s5_6[7..0];		 "Spare loCAL bus

"==============================================================================

