1 |
5 |
regttycomi |
`timescale 1ns / 1ps
|
2 |
|
|
//////////////////////////////////////////////////////////////////////////////////
|
3 |
|
|
// Company:
|
4 |
|
|
// Engineer:
|
5 |
|
|
//
|
6 |
|
|
// Create Date: 13:38:06 03/04/2009
|
7 |
|
|
// Design Name:
|
8 |
|
|
// Module Name: IDE_DMA
|
9 |
|
|
// Project Name:
|
10 |
|
|
// Target Devices:
|
11 |
|
|
// Tool versions:
|
12 |
|
|
// Description:
|
13 |
|
|
//
|
14 |
|
|
// Dependencies:
|
15 |
|
|
//
|
16 |
|
|
// Revision:
|
17 |
|
|
// Revision 0.01 - File Created
|
18 |
|
|
// Additional Comments:
|
19 |
|
|
//
|
20 |
|
|
//////////////////////////////////////////////////////////////////////////////////
|
21 |
|
|
|
22 |
|
|
//// Uncomment the following library declaration if instantiating
|
23 |
|
|
//// any Xilinx primitives in this code.
|
24 |
|
|
//library UNISIM;
|
25 |
|
|
//use UNISIM.VComponents.all;
|
26 |
|
|
|
27 |
|
|
module IDE_DMA(
|
28 |
|
|
// output IDE_DMA_STATE : out std_logic_vector(15 downto 0);
|
29 |
|
|
input CLK4 ,
|
30 |
|
|
input Phase3 ,
|
31 |
|
|
////// external pin interface
|
32 |
|
|
output reg iDK , // DMA acknowledge output to harddisk
|
33 |
|
|
input iDQ , // DMA request input from harddisk
|
34 |
|
|
input SiRdy1 , // Sync ready signal
|
35 |
|
|
input SiRdy2 , // Sync ready signal
|
36 |
|
|
////// system signal
|
37 |
|
|
input DMA_ARM , // extra signal to ARM the IDE DMA part
|
38 |
|
|
input PS2WrIDE , // 1'b1 if direction is from PS2 to IDE
|
39 |
|
|
input [2:0] UDMA , // the mode of the current transfer
|
40 |
|
|
input [2:0] MDMA,
|
41 |
|
|
output iDMARd , // active high signal to indicate DMA read
|
42 |
|
|
output iDMAWr , // active high signal to indicate DMA write
|
43 |
|
|
output reg iDMA_OE , // active high showing unit wishes to write bus
|
44 |
|
|
output reg iD_245_In , // active high 245 read envelope ( 1 clock before OE and 1 clock after)
|
45 |
|
|
output reg CRC_MUX , // inform system that need to drive the CRC Q to IDE bus
|
46 |
|
|
output reg CRC_ARM , // a signal indicate that to clear the CRC state
|
47 |
|
|
output reg CRC_ENB , // the enable for the CRC circuit
|
48 |
|
|
////// interface the RAM buffer, DMA machine will act according to buffer
|
49 |
|
|
input A0 , // address A0
|
50 |
|
|
input PA_Full , // high if PA is full, will be low only one block is cleared
|
51 |
|
|
input PA_HvSpace , // there is empty space for Port A
|
52 |
|
|
input PA_OD_Rdy , // some data availabe for output from Port A
|
53 |
|
|
input WithinABlock , // set within A block
|
54 |
|
|
input PA_AlmostFull , // stop if the buffer is almost full
|
55 |
|
|
input PA_Empty , // high if PA is empty
|
56 |
|
|
output IDE_DSTB, // high if we wish to strobe data
|
57 |
|
|
output reg HWOE, // high to select high page to output
|
58 |
|
|
output reg RegEA,
|
59 |
|
|
output reg IncAddrA ,
|
60 |
|
|
output reg EnbA , // enable and the control signal
|
61 |
|
|
output reg WrA
|
62 |
|
|
);
|
63 |
|
|
|
64 |
|
|
//////
|
65 |
|
|
|
66 |
|
|
//// ================================
|
67 |
|
|
////////////////////////////////////////////////
|
68 |
|
|
// signals
|
69 |
|
|
// NDMA : iDQ,iDK,iWr,iRd,iRDY
|
70 |
|
|
// UDI : iDQ,iDK,STOP,HDMARDY,DSTROBE
|
71 |
|
|
// UHO : iDQ,iDK,STOP,HSTROBE,DDMARDY
|
72 |
|
|
//////////////////////////////////////
|
73 |
|
|
reg HDMARDY,HSTROBE,STOP;
|
74 |
|
|
reg ND_Rd,ND_Wr;
|
75 |
|
|
|
76 |
|
|
wire NBrkOut; // wire to break out when buffer is empty
|
77 |
|
|
reg iWait;
|
78 |
|
|
wire UDMAC,MDMAC;
|
79 |
|
|
reg ND_ARM;
|
80 |
|
|
reg UHO_ARM;
|
81 |
|
|
reg UDI_ARM; // the UDI enable wire
|
82 |
|
|
reg ILatch; // the latch to control the data path for CRC calculation
|
83 |
|
|
//// ========
|
84 |
|
|
wire Proceed; // wire to proceed to output data in buffer
|
85 |
|
|
wire XiRdy1; // signal to indicate there is a transition
|
86 |
|
|
|
87 |
|
|
parameter iIdle1 = 6'b00_0000;
|
88 |
|
|
parameter iIdle2 = 6'b00_0001;
|
89 |
|
|
parameter ND_2 = 6'b00_0010;
|
90 |
|
|
parameter ND_3 = 6'b00_0011;
|
91 |
|
|
parameter ND_4 = 6'b00_0100;
|
92 |
|
|
parameter ND_5 = 6'b00_0101;
|
93 |
|
|
parameter ND_6 = 6'b00_0110;
|
94 |
|
|
parameter ND_7 = 6'b00_0111;
|
95 |
|
|
parameter ND_8 = 6'b00_1000;
|
96 |
|
|
parameter ND_9 = 6'b00_1001;
|
97 |
|
|
parameter ND_A = 6'b00_1010;
|
98 |
|
|
parameter ND_B = 6'b00_1011;
|
99 |
|
|
parameter ND_C = 6'b00_1100;
|
100 |
|
|
parameter Udi1 = 6'b01_0000;
|
101 |
|
|
parameter Udi2 = 6'b01_0001;
|
102 |
|
|
parameter Udi3 = 6'b01_0010;
|
103 |
|
|
//parameter Udi4 = 6'b01_0011;
|
104 |
|
|
parameter Udi10 = 6'b01_0100;
|
105 |
|
|
parameter Udi11 = 6'b01_0101;
|
106 |
|
|
parameter Udix1 = 6'b10_0001;
|
107 |
|
|
parameter Udix2 = 6'b10_0010;
|
108 |
|
|
parameter Udix3 = 6'b10_0011;
|
109 |
|
|
parameter Udix4 = 6'b10_0100;
|
110 |
|
|
parameter Udix5 = 6'b10_0101;
|
111 |
|
|
parameter Udix6 = 6'b10_0110;
|
112 |
|
|
parameter Uho_G = 6'b10_0111;
|
113 |
|
|
parameter Uhx_0 = 6'b10_1000;
|
114 |
|
|
parameter Uhx_1 = 6'b10_1001;
|
115 |
|
|
parameter Uhx_2 = 6'b10_1010;
|
116 |
|
|
parameter Uhx_3 = 6'b10_1011;
|
117 |
|
|
parameter Uhx_4 = 6'b10_1100;
|
118 |
|
|
parameter Uhx_5 = 6'b10_1101;
|
119 |
|
|
parameter Uhx_6 = 6'b10_1110;
|
120 |
|
|
//
|
121 |
|
|
parameter Uho_0 = 6'b11_0000;
|
122 |
|
|
parameter Uho_1 = 6'b11_0001;
|
123 |
|
|
parameter Uho_2 = 6'b11_0010;
|
124 |
|
|
parameter Uho_3 = 6'b11_0011;
|
125 |
|
|
parameter Uho_4 = 6'b11_0100;
|
126 |
|
|
parameter Uho_5 = 6'b11_0101;
|
127 |
|
|
parameter Uho_6 = 6'b11_0110;
|
128 |
|
|
parameter Uho_7 = 6'b11_0111;
|
129 |
|
|
parameter Uho_8 = 6'b11_1000;
|
130 |
|
|
parameter Uho_9 = 6'b11_1001;
|
131 |
|
|
parameter Uho_A = 6'b11_1010;
|
132 |
|
|
parameter Uho_B = 6'b11_1011;
|
133 |
|
|
parameter Uho_C = 6'b11_1100;
|
134 |
|
|
parameter Uho_D = 6'b11_1101;
|
135 |
|
|
parameter Uho_E = 6'b11_1110;
|
136 |
|
|
parameter Uho_F = 6'b11_1111;
|
137 |
|
|
|
138 |
|
|
|
139 |
|
|
reg [5:0] iSTATE;
|
140 |
|
|
reg [4:0] iCount;
|
141 |
|
|
reg PipeEmpty;
|
142 |
|
|
reg IDE_DSTB1;
|
143 |
|
|
|
144 |
|
|
////- ============== test stubs
|
145 |
|
|
//IDE_DMA_STATE(15 downto 7) <= "100000000"; // starts as 80xx
|
146 |
|
|
//IDE_DMA_STATE(6 downto 0) <= Count(6 downto 0);
|
147 |
|
|
//////////// ================== END OF TEST STUBBS =======================
|
148 |
|
|
|
149 |
|
|
|
150 |
|
|
|
151 |
|
|
////==========================================================
|
152 |
|
|
//- Normal DMA only signal
|
153 |
|
|
assign iDMAWr = (ND_ARM & ND_Wr) | ((UDI_ARM | UHO_ARM) & ~(STOP)); // the external DMA signal
|
154 |
|
|
assign iDMARd = (ND_ARM & ND_Rd) |
|
155 |
|
|
(UDI_ARM & HDMARDY) |
|
156 |
|
|
(UHO_ARM & ~HSTROBE);
|
157 |
|
|
|
158 |
|
|
// ===============================================================================
|
159 |
|
|
/// signal to stop normal DMA machine
|
160 |
|
|
// either 1/ iDQ is negated
|
161 |
|
|
// or 2/ During Host Out and no data in FIFO
|
162 |
|
|
// or 3/ During Drive In and FIFO is full
|
163 |
|
|
assign NBrkOut = ~iDQ | (PS2WrIDE & PA_Empty) | (~PS2WrIDE & PA_Full);
|
164 |
|
|
//// ============================================================================
|
165 |
|
|
|
166 |
|
|
//// ===================================
|
167 |
|
|
assign UDMAC = (UDMA[2] | UDMA[1] | UDMA[0]) & ~(MDMAC);
|
168 |
|
|
assign MDMAC = MDMA[2] | MDMA[1] | MDMA[0];
|
169 |
|
|
assign Proceed = PA_OD_Rdy | WithinABlock; // allow to output data when ready or we are in a transaction period
|
170 |
|
|
assign XiRdy1 = SiRdy1 ^ SiRdy2; // an early edge signal, lock the data to RAM
|
171 |
|
|
assign IDE_DSTB = (XiRdy1 & UDI_ARM) | ((UHO_ARM | ND_ARM) & ILatch );
|
172 |
|
|
|
173 |
|
|
always @(posedge CLK4) begin
|
174 |
|
|
IDE_DSTB1 <= IDE_DSTB;
|
175 |
|
|
CRC_ENB <= IDE_DSTB1 & ~IDE_DSTB; // trigger 1 clock after its deb
|
176 |
|
|
end
|
177 |
|
|
|
178 |
|
|
always @(posedge CLK4)begin
|
179 |
|
|
////DelayHSTB <= HSTROBE;
|
180 |
|
|
//HDMARDY <= ~STOP & (PA_HvSpace | (HDMARDY & (~PA_AlmostFull | ~XiRdy1))); //if we are almost full and enabled
|
181 |
|
|
|
182 |
|
|
if (DMA_ARM == 1'b0) begin
|
183 |
|
|
// ============================================================
|
184 |
|
|
UDI_ARM <= 1'b0;
|
185 |
|
|
UHO_ARM <= 1'b0;
|
186 |
|
|
STOP <= 1'b1; // always STOP
|
187 |
|
|
HDMARDY <= 1'b0; // Host always not ready
|
188 |
|
|
iWait <= 1'b0; // assume no wait
|
189 |
|
|
HSTROBE <= 1'b1; // HSTrobe Control by us
|
190 |
|
|
// ===================
|
191 |
|
|
ND_ARM <= 1'b0;
|
192 |
|
|
ND_Rd <= 1'b0; // no reading
|
193 |
|
|
ND_Wr <= 1'b0; // stop anything
|
194 |
|
|
ILatch <= 1'b0;
|
195 |
|
|
// ===================
|
196 |
|
|
iDK <= 1'b0;
|
197 |
|
|
iDMA_OE <= 1'b0; // no OE
|
198 |
|
|
iD_245_In <= 1'b0; // disable 245 driver direction control
|
199 |
|
|
CRC_ARM <= 1'b0; // clear the CRC machine
|
200 |
|
|
CRC_MUX <= 1'b0; // not selecting the CRC to output
|
201 |
|
|
// CRC_ENB <= 1'b0; // do not enable the CRC
|
202 |
|
|
// =============== RAM block control signal
|
203 |
|
|
RegEA <= 1'b0;
|
204 |
|
|
IncAddrA <= 1'b0;
|
205 |
|
|
EnbA <= 1'b0; // enable and the control signal
|
206 |
|
|
WrA <= 1'b0;
|
207 |
|
|
iCount <= 5'b0000;
|
208 |
|
|
HWOE <= 1'b0;
|
209 |
|
|
PipeEmpty <= 1'b1; // pipeline is empty for reset
|
210 |
|
|
iSTATE <= iIdle1; // keep the first state machine
|
211 |
|
|
// ==================
|
212 |
|
|
end else begin
|
213 |
|
|
// =========================================================
|
214 |
|
|
if (UHO_ARM == 1'b1) begin
|
215 |
|
|
if (SiRdy2 == 1'b1) begin
|
216 |
|
|
iWait <= 1'b1; // need to wait
|
217 |
|
|
iCount <= 5'd00;
|
218 |
|
|
end else begin
|
219 |
|
|
iCount <= iCount + 1;
|
220 |
|
|
if (iCount[4] == 1'b1) begin
|
221 |
|
|
iWait <= 1'b0; // clear the wait 16 clocks after SiRdy2 goes low
|
222 |
|
|
end
|
223 |
|
|
end
|
224 |
|
|
end //UHO_ARM
|
225 |
|
|
//============================================================
|
226 |
|
|
case (iSTATE)
|
227 |
|
|
iIdle1: begin
|
228 |
|
|
// ============================================================
|
229 |
|
|
UDI_ARM <= 1'b0; // Device In mode not ARM
|
230 |
|
|
STOP <= 1'b1; // always STOP
|
231 |
|
|
HDMARDY <= 1'b0; // always not ready
|
232 |
|
|
// ============================================================
|
233 |
|
|
UHO_ARM <= 1'b0; // Host Out mode not ARM
|
234 |
|
|
HSTROBE <= 1'b1; // HSTrobe Control by us
|
235 |
|
|
// ============================================================
|
236 |
|
|
ND_ARM <= 1'b0; // Normal DMA not ARM
|
237 |
|
|
ND_Rd <= 1'b0; // no reading
|
238 |
|
|
ND_Wr <= 1'b0; // stop anything
|
239 |
|
|
ILatch <= 1'b0;
|
240 |
|
|
// ===================
|
241 |
|
|
iDK <= 1'b0;
|
242 |
|
|
iDMA_OE <= 1'b0; // no OE
|
243 |
|
|
iD_245_In <= 1'b0; // disable control of 245 driver direction
|
244 |
|
|
CRC_ARM <= 1'b0; // clear the CRC machine
|
245 |
|
|
CRC_MUX <= 1'b0; // not selecting the CRC to output
|
246 |
|
|
// ===============
|
247 |
|
|
RegEA <= 1'b0;
|
248 |
|
|
IncAddrA <= 1'b0;
|
249 |
|
|
EnbA <= 1'b0; // enable and the control signal
|
250 |
|
|
WrA <= 1'b0;
|
251 |
|
|
iCount <= 5'b0000;
|
252 |
|
|
// ===============
|
253 |
|
|
iSTATE <= iIdle2; // next looping state
|
254 |
|
|
end
|
255 |
|
|
//// =============================================
|
256 |
|
|
iIdle2: begin
|
257 |
|
|
iCount <= 5'd00; // set counter as 00 in this state
|
258 |
|
|
if (iDQ == 1'b1) begin
|
259 |
|
|
if (UDMAC == 1'b1) begin //- Ultra DMA mode
|
260 |
|
|
if (PS2WrIDE == 1'b1) begin
|
261 |
|
|
if (Proceed == 1'b1) begin // try to proceed to output data
|
262 |
|
|
iSTATE <= Uho_0; // UW1: Write Data from PS2 to IDE
|
263 |
|
|
end
|
264 |
|
|
end else begin
|
265 |
|
|
if (PA_HvSpace == 1'b1) begin
|
266 |
|
|
iSTATE <= Udi1; // Read data from drive if we have space
|
267 |
|
|
end
|
268 |
|
|
end // PS2WrIDE
|
269 |
|
|
end else begin //- normal mode
|
270 |
|
|
if (PS2WrIDE == 1'b1) begin
|
271 |
|
|
if (Proceed == 1'b1) begin // if one block of data is valid
|
272 |
|
|
iSTATE <= ND_2;
|
273 |
|
|
end
|
274 |
|
|
end else begin
|
275 |
|
|
if (PA_HvSpace == 1'b1) begin
|
276 |
|
|
iSTATE <= ND_2; // if there is space
|
277 |
|
|
end
|
278 |
|
|
end //- PS2WrIDE
|
279 |
|
|
end //-UDMA
|
280 |
|
|
end else begin
|
281 |
|
|
iSTATE <= iIdle2; // loop here until iDQ = 1;
|
282 |
|
|
end // iDQ
|
283 |
|
|
end
|
284 |
|
|
////// =================================================
|
285 |
|
|
//-=== Multiword
|
286 |
|
|
//== mode 0 = 480nS cycle = 72 state = ND_3..ND36 = 36/36
|
287 |
|
|
//== mode 1 = 150nS cycle = 22 state = 01,02,03,04,18,19,20,21,22,23,24 = 12/10
|
288 |
|
|
//== mode 2 = 120nS cycle = 18 state = 01,02,03,04,05, 20,21,22,23 = 10/8
|
289 |
|
|
//// =====
|
290 |
|
|
ND_2: begin
|
291 |
|
|
iSTATE <= ND_3; // always
|
292 |
|
|
iDK <= iDQ; // directly map the request
|
293 |
|
|
ND_ARM <= 1'b1; // enter the normal DMA mode
|
294 |
|
|
iD_245_In <= ~PS2WrIDE; // turn 245 inwards if
|
295 |
|
|
end
|
296 |
|
|
//// ======
|
297 |
|
|
ND_3: begin
|
298 |
|
|
iDK <= iDQ; // directly map the request
|
299 |
|
|
if (NBrkOut == 1'b0) begin // if not breaking out
|
300 |
|
|
EnbA <= PS2WrIDE; // enable the RAM if writing
|
301 |
|
|
iSTATE <= ND_4; // goto next state if iDQ is not zero and we are within A Block
|
302 |
|
|
end else begin
|
303 |
|
|
iD_245_In <= 1'b0; // breaking out, always turn the buffer outwards
|
304 |
|
|
ND_ARM <= 1'b0; // no more arming of the signal
|
305 |
|
|
iSTATE <= iIdle1; // exit to check again
|
306 |
|
|
end
|
307 |
|
|
end
|
308 |
|
|
//// =====
|
309 |
|
|
ND_4: begin
|
310 |
|
|
iSTATE <= ND_5;
|
311 |
|
|
EnbA <= 1'b0; // already enabled, now turn off to conserve power
|
312 |
|
|
RegEA <= PS2WrIDE; // enable the registers if RAM access
|
313 |
|
|
end
|
314 |
|
|
//// =====
|
315 |
|
|
ND_5: begin
|
316 |
|
|
iSTATE <= ND_6; // goto next state ND_6 state
|
317 |
|
|
RegEA <= 1'b0; // latch gated, turn off now
|
318 |
|
|
iCount <= 5'd00; // reset the counter
|
319 |
|
|
iDMA_OE <= PS2WrIDE; // if write to drive, we will drive the data bus
|
320 |
|
|
end
|
321 |
|
|
//// =====
|
322 |
|
|
ND_6: begin
|
323 |
|
|
iSTATE <= ND_7; // goto next state ND_6 state
|
324 |
|
|
ND_Rd <= ~PS2WrIDE; // if read from drive then strobe external signal
|
325 |
|
|
ND_Wr <= PS2WrIDE; // if write to drive then strobe external signal
|
326 |
|
|
end
|
327 |
|
|
//// =============== determine cycle length =====================
|
328 |
|
|
ND_7: begin
|
329 |
|
|
iCount <= iCount + 1; //count less 5 for processing
|
330 |
|
|
if (((iCount == 5'd05) && (MDMA[2] == 1'b1)) || // strobe width is 10 clks
|
331 |
|
|
((iCount == 5'd07) && (MDMA[1] == 1'b1)) || // strobe width is 12 clks
|
332 |
|
|
(iCount == 5'd31) ) begin // strobe width is 36 clks
|
333 |
|
|
iSTATE <= ND_8; // set end Phase
|
334 |
|
|
end
|
335 |
|
|
end
|
336 |
|
|
//// ===============
|
337 |
|
|
ND_8: begin
|
338 |
|
|
ILatch <= ~PS2WrIDE; // if read from drive then enable input latch
|
339 |
|
|
iSTATE <= ND_9; // proceed if I/O ready
|
340 |
|
|
end
|
341 |
|
|
ND_9: begin
|
342 |
|
|
// if (SiRdy2 == 1'b1) begin
|
343 |
|
|
iSTATE <= ND_A; // proceed if I/O ready
|
344 |
|
|
// end
|
345 |
|
|
end
|
346 |
|
|
//// ===============
|
347 |
|
|
ND_A: begin
|
348 |
|
|
WrA <= ~PS2WrIDE; // if mode is read from drive then we pulse RAM
|
349 |
|
|
EnbA <= ~PS2WrIDE; // if mode is read from drive then we pulse RAM
|
350 |
|
|
iCount <= 5'd00; // reset counter
|
351 |
|
|
iSTATE <= ND_B;
|
352 |
|
|
end
|
353 |
|
|
ND_B: begin
|
354 |
|
|
WrA <= 1'b0; // always disable internal RAM Block write pulse
|
355 |
|
|
EnbA <= 1'b0; // always disable the RAM Block control signal
|
356 |
|
|
ND_Rd <= 1'b0; // always turn off external strobe
|
357 |
|
|
ND_Wr <= 1'b0; // always turn off external strobes now
|
358 |
|
|
ILatch <= 1'b0; // switch off data latch
|
359 |
|
|
IncAddrA <= 1'b1; // inc internal RAM Block address to next location
|
360 |
|
|
iSTATE <= ND_C;
|
361 |
|
|
end
|
362 |
|
|
//// ====================== end Phase
|
363 |
|
|
ND_C: begin
|
364 |
|
|
iDMA_OE <= 1'b0; // turn off the internal busdrivers
|
365 |
|
|
IncAddrA <= 1'b0; // turn off RAM Block address
|
366 |
|
|
HWOE <= A0; // select the next output data
|
367 |
|
|
iCount <= iCount + 1; //count less 5 for processing
|
368 |
|
|
if (((iCount == 5'd03) && (MDMA[2] == 1'b1)) || // recharge is 8 clks
|
369 |
|
|
((iCount == 5'd05) && (MDMA[1] == 1'b1)) || // recharge is 10 clks
|
370 |
|
|
(iCount == 5'd31) ) begin // recharge is 36 clks
|
371 |
|
|
iSTATE <= ND_3; // loop again
|
372 |
|
|
end
|
373 |
|
|
end
|
374 |
|
|
////-============================================================
|
375 |
|
|
//- Ultra DMA Drive In mode - we read from drive and write to FIFO
|
376 |
|
|
////-============================================================
|
377 |
|
|
Udi1: begin // Udi1 state
|
378 |
|
|
UDI_ARM <= 1'b1; // now the DMA_machine is UDI controlled
|
379 |
|
|
iDK <= 1'b0; // no DMA first
|
380 |
|
|
iDMA_OE <= 1'b0; // ensure we are not driving the FPGA output
|
381 |
|
|
STOP <= 1'b1; // set to stop first
|
382 |
|
|
HDMARDY <= 1'b0; // set to not ready first
|
383 |
|
|
if (Phase3 == 1'b1) begin
|
384 |
|
|
iSTATE <= Udi2;
|
385 |
|
|
end
|
386 |
|
|
end
|
387 |
|
|
Udi2: begin // Udi2 state -- at least one clock
|
388 |
|
|
if (iDQ == 1'b1) begin
|
389 |
|
|
if ((Phase3 == 1'b1) && (SiRdy2 == 1'b1)) begin // wait until the drive drives high the IORDY signal
|
390 |
|
|
iSTATE <= Udi3;
|
391 |
|
|
end
|
392 |
|
|
end else begin
|
393 |
|
|
iSTATE <= iIdle1; // exit to idle if iDQ suddenly gone
|
394 |
|
|
end
|
395 |
|
|
end
|
396 |
|
|
Udi3: begin // Udi3 state -- at least one clock
|
397 |
|
|
iDK <= 1'b1; // we issue DMA ready for iDQ
|
398 |
|
|
iD_245_In <= 1'b1; // turn the driver inwards
|
399 |
|
|
CRC_ARM <= 1'b1; // start the CRC machine
|
400 |
|
|
if (Phase3 == 1'b1) begin
|
401 |
|
|
iSTATE <= Udi10;
|
402 |
|
|
end
|
403 |
|
|
end
|
404 |
|
|
//// ==================
|
405 |
|
|
//HDMARDY <= ~STOP & (PA_HvSpace | (HDMARDY & ~(PA_AlmostFull & XiRdy1))); //if we are almost full and enabled
|
406 |
|
|
|
407 |
|
|
Udi10: begin
|
408 |
|
|
IncAddrA <= 1'b0; // always clear the increment address pulse
|
409 |
|
|
if (XiRdy1 == 1'b1) begin // delay 2 and 3
|
410 |
|
|
EnbA <= 1'b1;
|
411 |
|
|
WrA <= 1'b1;
|
412 |
|
|
// CRC_ENB <= 1'b1; // calculate the CRC
|
413 |
|
|
iSTATE <= Udi11;
|
414 |
|
|
end else begin
|
415 |
|
|
if (iDQ == 1'b1) begin // if iDQ still valid
|
416 |
|
|
HDMARDY <= ~PA_AlmostFull; //20100623 still have space
|
417 |
|
|
STOP <= 1'b0; // 20100623 not stopping
|
418 |
|
|
iSTATE <= Udi10; // loop here
|
419 |
|
|
end else begin
|
420 |
|
|
HDMARDY <= 1'b0; //20100623
|
421 |
|
|
STOP <= 1'b1; //20100623
|
422 |
|
|
iSTATE <= Udix1; // no more iDQ then exit
|
423 |
|
|
end
|
424 |
|
|
end
|
425 |
|
|
end
|
426 |
|
|
Udi11: begin
|
427 |
|
|
iSTATE <= Udi10; // loop back for fast processing
|
428 |
|
|
EnbA <= 1'b0; // no more RAM enable
|
429 |
|
|
WrA <= 1'b0; // no more Wr enable
|
430 |
|
|
// CRC_ENB <= 1'b0; // no more CRC
|
431 |
|
|
IncAddrA <= 1'b1; // just increment the address
|
432 |
|
|
end
|
433 |
|
|
//// ========================= exit routine ====================
|
434 |
|
|
Udix1: begin
|
435 |
|
|
if ((Phase3 == 1'b1) && (SiRdy2 == 1'b1)) begin // wait until the drive drives high the IORDY signal
|
436 |
|
|
iSTATE <= Udix2;
|
437 |
|
|
end
|
438 |
|
|
end
|
439 |
|
|
Udix2: begin
|
440 |
|
|
CRC_MUX <= 1'b1; //20100622 add one clock earlier to turn the CRC_MUX to data bus
|
441 |
|
|
iD_245_In <= 1'b0; //20100622 add one clock earlier to turn the 245 outwarts
|
442 |
|
|
if (Phase3 == 1'b1) begin
|
443 |
|
|
iSTATE <= Udix3; // wait at least one clock
|
444 |
|
|
end
|
445 |
|
|
end
|
446 |
|
|
Udix3: begin
|
447 |
|
|
iDMA_OE <= 1'b1; // 20100622 add one clock earlier drive high the OE to output the CRC address
|
448 |
|
|
if (Phase3 == 1'b1) begin
|
449 |
|
|
iSTATE <= Udix4; // wait at least two clock
|
450 |
|
|
end
|
451 |
|
|
end
|
452 |
|
|
Udix4: begin
|
453 |
|
|
if (Phase3 == 1'b1) begin
|
454 |
|
|
iSTATE <= Udix5; // wait at least two clock
|
455 |
|
|
end
|
456 |
|
|
end
|
457 |
|
|
Udix5: begin
|
458 |
|
|
iDK <= 1'b0; // stop the iDK
|
459 |
|
|
if (Phase3 == 1'b1) begin
|
460 |
|
|
iSTATE <= Udix6; // wait at least two clock
|
461 |
|
|
end
|
462 |
|
|
end
|
463 |
|
|
Udix6: begin
|
464 |
|
|
if (Phase3 == 1'b1) begin
|
465 |
|
|
iSTATE <= iIdle1; // wait at least two clock
|
466 |
|
|
end
|
467 |
|
|
end
|
468 |
|
|
////-======================================================
|
469 |
|
|
//- Ultra DMA Host Out mode - we read from DMA RAM and write to drive
|
470 |
|
|
//- only here we detemine the cycle time
|
471 |
|
|
//- UDMA(2) = 60nS cycle time = 8 clock
|
472 |
|
|
//- UDMA(1) = 80nS (81.6) = 12 clock
|
473 |
|
|
//- UDMA(0) = 120nS cycle time = 16 clock
|
474 |
|
|
////-======================================================
|
475 |
|
|
Uho_0: begin // UW1 state
|
476 |
|
|
UHO_ARM <= 1'b1;
|
477 |
|
|
iDK <= 1'b1; // enable the iDKs
|
478 |
|
|
STOP <= 1'b1; // STOP the system first
|
479 |
|
|
HSTROBE <= 1'b1; // STROBE is high
|
480 |
|
|
EnbA <= PipeEmpty; // enable the RAM if the pipeline is empty
|
481 |
|
|
iSTATE <= Uho_1; // UW2 state
|
482 |
|
|
end
|
483 |
|
|
//// ======= entry from temporary stop with refill data =================
|
484 |
|
|
Uho_1: begin // UW2 state
|
485 |
|
|
iDK <= 1'b1; // DMA ready
|
486 |
|
|
EnbA <= 1'b0; // already enable the RAM, turn it off
|
487 |
|
|
RegEA <= PipeEmpty; // enable register if the pipeline is empty
|
488 |
|
|
iD_245_In <= 1'b0; // turn the driver outwards, data is now put to bus
|
489 |
|
|
iSTATE <= Uho_2; // UW3 state
|
490 |
|
|
end
|
491 |
|
|
//// =======
|
492 |
|
|
Uho_2: begin
|
493 |
|
|
RegEA <= 1'b0; // register already enabled
|
494 |
|
|
HWOE <= ~PipeEmpty ^ A0; // if empty uses A0; if not empty uses ~A0
|
495 |
|
|
iSTATE <= Uho_3; // UW4 state
|
496 |
|
|
end
|
497 |
|
|
//// ========
|
498 |
|
|
Uho_3: begin // UW4 state
|
499 |
|
|
STOP <= 1'b0; // remove the STOP signal
|
500 |
|
|
if ((SiRdy2 == 1'b0) && (Phase3 == 1'b1)) begin
|
501 |
|
|
iSTATE <= Uho_4; // wait till ready
|
502 |
|
|
iDMA_OE <= 1'b1; // drive the OE data
|
503 |
|
|
end
|
504 |
|
|
end
|
505 |
|
|
//// ======== wait 2 clocks ; restart from old break
|
506 |
|
|
Uho_4: begin
|
507 |
|
|
if ((SiRdy2 == 1'b0) && (Phase3 == 1'b1)) begin
|
508 |
|
|
IncAddrA <= PipeEmpty; //Increment the address if the pipe is empty
|
509 |
|
|
iSTATE <= Uho_5; //wait 1 clock
|
510 |
|
|
end
|
511 |
|
|
end
|
512 |
|
|
//// ==== already have valid data in the bus
|
513 |
|
|
Uho_5: begin
|
514 |
|
|
IncAddrA <= 1'b0; // no more increment the address
|
515 |
|
|
if ((SiRdy2 == 1'b0) && (Phase3 == 1'b1)) begin
|
516 |
|
|
EnbA <= 1'b1; // after increment address, enable the RAM
|
517 |
|
|
iSTATE <= Uho_6;
|
518 |
|
|
end
|
519 |
|
|
end
|
520 |
|
|
/// === one clock +ve data advance offset data bus
|
521 |
|
|
Uho_6: begin
|
522 |
|
|
iSTATE <= Uho_7; // jump into the main loop
|
523 |
|
|
EnbA <= 1'b0; // disable the RAM
|
524 |
|
|
iWait <= 1'b0; // no need to wait here
|
525 |
|
|
HSTROBE <= 1'b0; // first strobe edge is low
|
526 |
|
|
CRC_ARM <= 1'b1; // enable the CRC machine
|
527 |
|
|
end
|
528 |
|
|
//// ====== host output loop is here ==================
|
529 |
|
|
Uho_7: begin
|
530 |
|
|
/// data bus and associate control signal
|
531 |
|
|
ILatch <= 1'b1; // house keeping enable data bus ilatch for CRC calculation
|
532 |
|
|
/// determine buffer content, check if more data to send
|
533 |
|
|
if (PA_Empty == 1'b1) begin
|
534 |
|
|
iSTATE <= Uho_F; // last data on bus and no more data, normal exit now
|
535 |
|
|
end else begin
|
536 |
|
|
RegEA <= UDMA[2]; // enable the register now if UDMA-mode 2
|
537 |
|
|
iSTATE <= Uho_8; // more data to send, keep looping
|
538 |
|
|
end
|
539 |
|
|
end
|
540 |
|
|
////
|
541 |
|
|
Uho_8: begin
|
542 |
|
|
/// data bus control signal
|
543 |
|
|
RegEA <= UDMA[1]; // enable the register now if UDMA-mode 1 / disable if mode 2
|
544 |
|
|
ILatch <= 1'b0; // stop the input data latch and pass data to CRC engine
|
545 |
|
|
HWOE <= (UDMA[2] == 1'b1) ? A0 : HWOE;
|
546 |
|
|
///////////
|
547 |
|
|
if (UDMA[2] == 1'b1) begin
|
548 |
|
|
IncAddrA <= 1'b1; // increase the address
|
549 |
|
|
iSTATE <= Uho_D; // 4 clocks 7,8,D,E
|
550 |
|
|
end else begin
|
551 |
|
|
iSTATE <= Uho_9;
|
552 |
|
|
end
|
553 |
|
|
end
|
554 |
|
|
/////// ==================================
|
555 |
|
|
Uho_9: begin
|
556 |
|
|
/// data bus control signal
|
557 |
|
|
RegEA <= 1'b0; // disable the register access always
|
558 |
|
|
HWOE <= (UDMA[1] == 1'b1) ? A0 : HWOE;
|
559 |
|
|
/////////
|
560 |
|
|
if (UDMA[1] == 1'b1) begin
|
561 |
|
|
iSTATE <= Uho_C; // 6 clocks 7,8,9,C,D,E
|
562 |
|
|
end else begin
|
563 |
|
|
iSTATE <= Uho_A;
|
564 |
|
|
end
|
565 |
|
|
end
|
566 |
|
|
////// ===================================
|
567 |
|
|
Uho_A: begin
|
568 |
|
|
RegEA <= UDMA[0]; // enable the register now if UDMA-mode 0 / disable otherwise
|
569 |
|
|
iSTATE <= Uho_B; // 8 cycles 7,8,9,A,B,C,D,E
|
570 |
|
|
end
|
571 |
|
|
///// middle point of the strobe //////======================
|
572 |
|
|
Uho_B: begin
|
573 |
|
|
/// data bus control signal
|
574 |
|
|
RegEA <= 1'b0; // disable the register access always
|
575 |
|
|
HWOE <= (UDMA[0] == 1'b1) ? A0 : HWOE;
|
576 |
|
|
iSTATE <= Uho_C;
|
577 |
|
|
end
|
578 |
|
|
Uho_C: begin
|
579 |
|
|
iSTATE <= Uho_D;
|
580 |
|
|
IncAddrA <= 1'b1; // increase the address for one clock
|
581 |
|
|
end
|
582 |
|
|
Uho_D: begin
|
583 |
|
|
iSTATE <= Uho_E;
|
584 |
|
|
IncAddrA <= 1'b0; // no more increment the address
|
585 |
|
|
EnbA <= 1'b1; // after increment address, enable the RAM
|
586 |
|
|
end
|
587 |
|
|
Uho_E: begin
|
588 |
|
|
EnbA <= 1'b0; // disable the RAM
|
589 |
|
|
if (iDQ == 1'b0) begin // check iDQ
|
590 |
|
|
iSTATE <= Uhx_0; // lost iDQ abnormal exit
|
591 |
|
|
end else begin
|
592 |
|
|
if (iWait == 1'b0) begin
|
593 |
|
|
// CRC_ENB <= 1'b1; // data stobed, so can calculate CRC
|
594 |
|
|
HSTROBE <= ~HSTROBE; // toggle the strobe and keep
|
595 |
|
|
iSTATE <= Uho_7; // loop back for another data
|
596 |
|
|
end else begin
|
597 |
|
|
iSTATE <= Uho_E; // loop here until no more wait
|
598 |
|
|
end
|
599 |
|
|
end
|
600 |
|
|
end
|
601 |
|
|
//// =========================== end of host output loop =========
|
602 |
|
|
/// === all host data out now, determine exit or re-run refill =====================
|
603 |
|
|
Uho_F: begin
|
604 |
|
|
PipeEmpty <= 1'b1; // pipe is empty
|
605 |
|
|
ILatch <= 1'b0; // stop the input data latch and pass data to CRC engine
|
606 |
|
|
if (Phase3 == 1'b1) begin
|
607 |
|
|
iSTATE <= Uho_G; // exit now
|
608 |
|
|
end
|
609 |
|
|
end
|
610 |
|
|
Uho_G: begin
|
611 |
|
|
STOP <= 1'b1; // drive high the stop signal
|
612 |
|
|
if (Phase3 == 1'b1) begin
|
613 |
|
|
if ((SiRdy2 == 1'b1) && (iDQ == 1'b0)) begin // wait here until ready and DMA request is gone
|
614 |
|
|
iSTATE <= Uhx_3; // wait at least two clock
|
615 |
|
|
end else begin
|
616 |
|
|
if (PA_OD_Rdy == 1'b1) begin // or wait until there is one block of data to transfer out
|
617 |
|
|
EnbA <= PipeEmpty; // enable the RAM if the pipeline is empty (always 1'b1)
|
618 |
|
|
iSTATE <= Uho_1; // jump back into the main loop if there is data
|
619 |
|
|
end
|
620 |
|
|
end
|
621 |
|
|
end
|
622 |
|
|
end
|
623 |
|
|
//// ==== lost of iDQ, data still in RAM BLOCK Register exit ============
|
624 |
|
|
Uhx_0: begin
|
625 |
|
|
PipeEmpty <= 1'b0; // clear flag as the UHO machine has unread content
|
626 |
|
|
if (Phase3 == 1'b1) begin
|
627 |
|
|
iSTATE <= Uhx_1;
|
628 |
|
|
end
|
629 |
|
|
end
|
630 |
|
|
Uhx_1: begin
|
631 |
|
|
if (Phase3 == 1'b1) begin
|
632 |
|
|
iSTATE <= Uhx_2; // wait at least two clock
|
633 |
|
|
end
|
634 |
|
|
end
|
635 |
|
|
Uhx_2: begin
|
636 |
|
|
STOP <= 1'b1; // drive high the stop signal
|
637 |
|
|
if ((Phase3 == 1'b1) && (SiRdy2 == 1'b1) && (iDQ == 1'b0)) begin // wait here until ready and DMA request is gone
|
638 |
|
|
iSTATE <= Uhx_3; // wait at least two clock
|
639 |
|
|
end
|
640 |
|
|
end
|
641 |
|
|
Uhx_3: begin
|
642 |
|
|
HSTROBE <= 1'b1; // must set high the HSTROBE signal now
|
643 |
|
|
CRC_MUX <= 1'b1; // turn the CRC_MUX to data bus
|
644 |
|
|
if (Phase3 == 1'b1) begin
|
645 |
|
|
iSTATE <= Uhx_4; // wait at least two clock
|
646 |
|
|
end
|
647 |
|
|
end
|
648 |
|
|
Uhx_4: begin
|
649 |
|
|
if (Phase3 == 1'b1) begin // wait here until ready is gone
|
650 |
|
|
iSTATE <= Uhx_5; // wait at least two clock
|
651 |
|
|
end
|
652 |
|
|
end
|
653 |
|
|
Uhx_5: begin
|
654 |
|
|
iDK <= 1'b0; // stop the iDK
|
655 |
|
|
if (Phase3 == 1'b1) begin
|
656 |
|
|
iSTATE <= Uhx_6; // wait at least two clock
|
657 |
|
|
end
|
658 |
|
|
end
|
659 |
|
|
Uhx_6: begin
|
660 |
|
|
if (Phase3 == 1'b1) begin
|
661 |
|
|
iSTATE <= iIdle1; // wait at least two clock
|
662 |
|
|
end
|
663 |
|
|
end
|
664 |
|
|
//// ======================== end of UHO loop =================
|
665 |
|
|
default: begin
|
666 |
|
|
iSTATE <= iIdle1; // jump to idle for rouge states
|
667 |
|
|
end
|
668 |
|
|
endcase
|
669 |
|
|
end // DMA_ARM
|
670 |
|
|
end // clock edges
|
671 |
|
|
|
672 |
|
|
endmodule
|