summaryrefslogtreecommitdiffstats
path: root/newnewexi.pld
blob: 0e2bb9ddcc3c20d1e0173df3fafea1e37cc4ba29 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
Name       newnewexi.pld;
Partno     ;
Date       ;
Revision   ;
Designer   ;
Company    ;
Assembly   ;
Location   ;
Device     F1502ISPTQFP44;

/***********************************************************/
/*                                                         */
/*                                                         */
/*                                                         */
/***********************************************************/
/*  Allowable Target Device                                */
/***********************************************************/

/** EXI-side pins  **/

Pin 37 = EXI_CLK;	/*  IN: EXI bit clock (act on rising edge) */
Pin 8 = !EXI_CS;	/*  IN: EXI chip select (active-low) - device in standby when FALSE */
Pin 10 = EXI_DO;	/* OUT: EXI data (slave out) */
Pin 11 = EXI_DI;	/*  IN: EXI data (slave in) */
Pin 12 = EXI_INT;	/* OUT: EXI interrupt (not used) */

/** USB-side pins  **/

Pin [35..33, 31, 30, 28, 27, 25] = [FIFO0..7];	/* I/O: USB data lines */
Pin 23 = !USB_RXF;				/*  IN: USB data in FIFO? */
Pin 22 = !USB_TXE;				/*  IN: USB can write? */
Pin 21 = !USB_RD; 				/* OUT: USB read request (need RXF TRUE) */
Pin 20 = USB_WR;				/* OUT: USB write request (need TXE TRUE) */
Pin 18 = !USB_PWREN;				/*  IN: USB bus ready? */

/** Extra pins **/
Pin 6 = LED;	/* OUT: Master-controlled LED */

/**   Declarations and Intermediate Variable Definitions  **/

Node [EXI_CMD3..0];		/* Command from EXI (shifted in) */
/* Node [EXI_DATA0..7]; */	/* Data from EXI (shifted in) */
Node [EXI_SEQ0..3];		/* Current EXI clock counter */

Node MODE_RD;		/* EXI device read request */
Node MODE_WR;		/* EXI write request */
Node MODE_ID;		/* EXI identify request */
Node LED_STATE;		/* EXI requested LED on? */
Node RESET_MODE;	/* Reset since last clock */
/* Node WRITE_NOW; */	/* Writing USB data now? */

Field USB_Data = [FIFO7..0];		/* USB FIFO data (if USB_RD TRUE) */
Field EXI_Command = [EXI_CMD3..0];	/* EXI command field */
/* Field EXI_Data = [EXI_DATA7..0]; */
Field EXI_State = [EXI_SEQ3..0];	/* Clock state */

Enable = EXI_CS & USB_PWREN;
LED = LED_STATE # !Enable;	/* LED should be on if USB isn't set up yet, or if requested by EXI */

$Repeat i = [0..3]
/* EXI_SEQ state machine clocked by EXI (assuming we're selected) */
EXI_SEQ{i}.CKMUX = EXI_CLK;
EXI_SEQ{i}.CE = Enable;

EXI_CMD{i}.CKMUX = EXI_CLK;
EXI_CMD{i}.CE = EXI_State:'h'{3-i} & Enable;
EXI_CMD{i}.D = EXI_DI;
$RepEnd

$Repeat i = [0..7]
FIFO{i}.CKMUX = EXI_CLK;
FIFO{i}.CE = EXI_State:'h'{11-i} & Enable;
FIFO{i}.D = EXI_DI;
FIFO{i}.OE = USB_WR;
$RepEnd

MODE_RD.CKMUX = EXI_CLK;
MODE_RD.CE = Enable;
MODE_ID.CKMUX = EXI_CLK;
MODE_ID.CE = Enable;
MODE_WR.CKMUX = EXI_CLK;
MODE_WR.CE = Enable;
/* WRITE_NOW.CKMUX = EXI_CLK; */
/* WRITE_NOW.CE = Enable; */

EXI_DO.CKMUX = EXI_CLK;
EXI_DO.CE = Enable;

USB_RD.CKMUX = EXI_CLK;
USB_RD.CE = Enable;
USB_WR.CKMUX = EXI_CLK;
USB_WR.CE = Enable;

LED_STATE.CKMUX = EXI_CLK;
LED_STATE.CE = Enable;

RESET_MODE.D = Reset;
RESET_MODE.CKMUX = EXI_CLK; /* don't care if this is clocked while !Enable */
Reset = !Enable & !RESET_MODE;

/* Set .AR/.AP signals here to reset stuff when the chip is deselected or USB is lost. */
EXI_State.AR = Reset;
EXI_Command.AR = Reset;
EXI_DO.AR = Reset;

MODE_RD.AR = Reset;
MODE_ID.AR = Reset;
MODE_WR.AR = Reset;
/* WRITE_NOW.AR = Reset; */

USB_RD.AR = Reset;
USB_WR.AR = Reset;

SequenceD EXI_State {
	Present 'd'0 Next 'd'1 Out MODE_RD.K Out MODE_ID.K Out MODE_WR.K Out USB_RD.K Out USB_WR.K;
	Present 'd'1 Next 'd'2;
	Present 'd'2 Next 'd'3;
	Present 'd'3
		/* .D is used here because EXI_Command (Q) is not necessarily updated by the time this logic occurs. */
		If EXI_Command:'h'A & USB_RXF Next 'd'4 /* Ready to read */
			Out MODE_RD.J /* Enter reading mode. */
			Out EXI_DO /* Tell GC. */
			Out USB_RD.J /* Trigger USB read */;
		If EXI_Command:'h'A & !USB_RXF Next 'd'15 /* Not ready to read. EXI_DO stays low. */;
		Default Next 'd'4;
	Present 'd'4
		If EXI_Command:'h'9 Next 'd'5 Out MODE_ID.J Out EXI_DO /* Send bit 7 of ID byte */;
		If EXI_Command:'h'B & USB_TXE Next 'd'5 /* Ready to write */
			Out MODE_WR.J /* Enter writing mode */
			Out EXI_DO /* Write TX status */;
		If EXI_Command:'h'B & !USB_TXE Next 'd'15; /* Not ready to write. */
		If EXI_Command:'h'C & USB_TXE Next 'd'15 Out EXI_DO;
		If EXI_Command:'h'D & USB_RXF Next 'd'15 Out EXI_DO;
		If EXI_Command:'h'7 Next 'd'15 Out LED_STATE.J;
		If EXI_Command:'h'8 Next 'd'15 Out LED_STATE.K;
		Default Next 'd'5;
	Present 'd'5
		/* ID bit 6: 0 */
		Next 'd'6;
	Present 'd'6
		/* ID bit 5: 0 */
		Next 'd'7;
	Present 'd'7
		/* ID bit 4: 0 */
		If MODE_RD & FIFO7.IO Next 'd'8 Out EXI_DO;
		Default Next 'd'8;
	Present 'd'8
		/* ID bit 3: 1 */
		If MODE_ID Next 'd'9 Out EXI_DO;
		If MODE_RD & FIFO6.IO Next 'd'9 Out EXI_DO;
		Default Next 'd'9;
	Present 'd'9
		/* ID bit 2: 1 */
		If MODE_ID Next 'd'10 Out EXI_DO;
		If MODE_RD & FIFO5.IO Next 'd'10 Out EXI_DO;
		Default Next 'd'10;
	Present 'd'10
		/* ID bit 1: 1 */
		If MODE_ID Next 'd'11 Out EXI_DO;
		If MODE_RD & FIFO4.IO Next 'd'11 Out EXI_DO;
		Default Next 'd'11;
	Present 'd'11
		/* ID bit 0: 0 */
		If MODE_RD & FIFO3.IO Next 'd'12 Out EXI_DO;
		Default Next 'd'12;
	Present 'd'12
		If MODE_RD & FIFO2.IO Next 'd'13 Out EXI_DO;
		/* B CMD: Received the data over EXI, let's write it now. */
		If MODE_WR Next 'd'13 Out USB_WR.J;
		Default Next 'd'13;
	Present 'd'13
		If MODE_RD & FIFO1.IO Next 'd'14 Out EXI_DO;
		Default Next 'd'14;
	Present 'd'14
		If MODE_RD & FIFO0.IO Next 'd'15 Out EXI_DO;
		If MODE_WR Next 'd'15 Out USB_WR.K;
		Default Next 'd'15;
	Present 'd'15
		Next 'd'15
		Out USB_RD.K /* Reset all pins */
		Out USB_WR.K
		Out MODE_RD.K
		Out MODE_WR.K
		Out MODE_ID.K;
}