1 |
5 |
regttycomi |
`timescale 1ns / 1ps
|
2 |
|
|
//////////////////////////////////////////////////////////////////////////////////
|
3 |
|
|
// Company:
|
4 |
|
|
// Engineer:
|
5 |
|
|
//
|
6 |
|
|
// Create Date: 10:31:00 12/08/2008
|
7 |
|
|
// Design Name:
|
8 |
|
|
// Module Name: PS2_DMA - Behavioral
|
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 |
|
|
module PS2_DMA (
|
23 |
|
|
// PS2_DMA_STATE : out std_logic_vector(15 downto 0);
|
24 |
|
|
input CLK4, // 146.6MHz clock input
|
25 |
|
|
input Phase3, // the phases
|
26 |
|
|
////// external pin interface
|
27 |
|
|
output reg cDQ, // DMA request output
|
28 |
|
|
input cDK, // DMA acknowledge input
|
29 |
|
|
input cRd, // read pulse
|
30 |
|
|
input DWrite, // write and counter pulse
|
31 |
|
|
////// controlling signal
|
32 |
|
|
input DMA_ARM , // signal from ctrllr to inits DMA
|
33 |
|
|
input PS2WrIDE , // level indicating that PS2 is DMA writing IDE bus
|
34 |
|
|
//// PS2 DMA connecting to RAM interface
|
35 |
|
|
input PB_OD_Rdy , // set high if at least 512 bytes in buffer (only check high order bits)
|
36 |
|
|
input PB_HvSpace , // set high if there is at least 512 bytes empty space in buffer (only check high order bits)
|
37 |
|
|
input WithinBBlock , // high if (AddrB(6) | AddrB(5)) = 1
|
38 |
|
|
input BBurstEnd , // high if AddrB = xxxx11111 = 1F
|
39 |
|
|
////
|
40 |
|
|
output reg IncAddrB ,
|
41 |
|
|
output RegEB , // pipeline register enable
|
42 |
|
|
output reg EnbB ,
|
43 |
|
|
output reg WrB
|
44 |
|
|
);
|
45 |
|
|
|
46 |
|
|
reg DTook;
|
47 |
|
|
reg DWrote;
|
48 |
|
|
|
49 |
|
|
// reworking the state machines at 100807
|
50 |
|
|
|
51 |
|
|
parameter PIdle = 5'b00000;
|
52 |
|
|
/// read phases
|
53 |
|
|
parameter PR20 = 5'b00100;
|
54 |
|
|
parameter PR21 = 5'b00101;
|
55 |
|
|
parameter PR22 = 5'b00110;
|
56 |
|
|
parameter PR23 = 5'b00111;
|
57 |
|
|
parameter PR32 = 5'b01000;
|
58 |
|
|
parameter PR37 = 5'b01001;
|
59 |
|
|
parameter PR38 = 5'b01010;
|
60 |
|
|
parameter PR38A = 5'b01011;
|
61 |
|
|
parameter PR38B = 5'b01100;
|
62 |
|
|
/// write phases
|
63 |
|
|
parameter PW01A = 5'b10001;
|
64 |
|
|
parameter PW01B = 5'b10010;
|
65 |
|
|
parameter PW01C = 5'b10011;
|
66 |
|
|
parameter PW01D = 5'b10100;
|
67 |
|
|
parameter PW32 = 5'b10101;
|
68 |
|
|
parameter PW35 = 5'b10110;
|
69 |
|
|
parameter PW36 = 5'b10111;
|
70 |
|
|
parameter PW37 = 5'b11000;
|
71 |
|
|
parameter PW38A = 5'b11001;
|
72 |
|
|
parameter PW38B = 5'b11010;
|
73 |
|
|
parameter PW38C = 5'b11011;
|
74 |
|
|
parameter PW38D = 5'b11100;
|
75 |
|
|
parameter PW40 = 5'b11101;
|
76 |
|
|
|
77 |
|
|
reg [4:0] PSST;
|
78 |
|
|
reg OPOvrRide;
|
79 |
|
|
|
80 |
|
|
////- ============== test stubs
|
81 |
|
|
//PS2_DMA_STATE (15 downto 6) <= "0000000000";
|
82 |
|
|
//PS2_DMA_STATE ( 5 downto 0) <= STATE(5 downto 0);
|
83 |
|
|
//TYPE GBState_type IS (A, B, C, D);
|
84 |
|
|
//SIGNAL GBState : GBState_Type;
|
85 |
|
|
|
86 |
|
|
//////////// ================== END OF TEST STUBBS =======================
|
87 |
|
|
|
88 |
|
|
assign RegEB = Phase3 & ( cRd | OPOvrRide );
|
89 |
|
|
|
90 |
|
|
//// ===================
|
91 |
|
|
|
92 |
|
|
always @(posedge CLK4) begin
|
93 |
|
|
if (DMA_ARM == 1'b0) begin
|
94 |
|
|
cDQ <= 1'b0; // always no request
|
95 |
|
|
DTook <= 1'b0;
|
96 |
|
|
DWrote <= 1'b0;
|
97 |
|
|
IncAddrB <= 1'b0;
|
98 |
|
|
OPOvrRide <= 1'b0;
|
99 |
|
|
EnbB <= 1'b0;
|
100 |
|
|
WrB <= 1'b0;
|
101 |
|
|
PSST <= PIdle;
|
102 |
|
|
end else begin
|
103 |
|
|
////===== State machine default state ======
|
104 |
|
|
case (PSST)
|
105 |
|
|
PIdle: begin
|
106 |
|
|
if (PS2WrIDE == 1'b0) begin // if reading from disk
|
107 |
|
|
cDQ <= 1'b0; // always 0 if we don't have enough data
|
108 |
|
|
if ((PB_OD_Rdy == 1'b1) && (Phase3 == 1'b1)) begin // if there is data in the buffer
|
109 |
|
|
PSST <= PR38; // go to PR38
|
110 |
|
|
end
|
111 |
|
|
end else begin
|
112 |
|
|
cDQ <= PB_HvSpace; // high if we have space
|
113 |
|
|
if ((cDK == 1'b1) && (Phase3 == 1'b1)) begin
|
114 |
|
|
PSST <= PW40; // PSST <= PW40A;
|
115 |
|
|
end
|
116 |
|
|
end
|
117 |
|
|
end
|
118 |
|
|
//////- ======== PS2 reading DMA states //////////////////////-
|
119 |
|
|
PR38: begin
|
120 |
|
|
cDQ <= 1'b0; // data not ready
|
121 |
|
|
DTook <= 1'b1; // increment address for the every burst
|
122 |
|
|
if (Phase3 == 1'b1) begin
|
123 |
|
|
PSST <= PR38A; // clock the state machine into correct phase
|
124 |
|
|
end
|
125 |
|
|
end
|
126 |
|
|
//////- ========================================================
|
127 |
|
|
PR38A: begin
|
128 |
|
|
EnbB <= DTook; // be generous, 4 cycle enable for RAM data
|
129 |
|
|
if (Phase3 == 1'b1) begin
|
130 |
|
|
PSST <= PR38B; // one dummy state
|
131 |
|
|
end
|
132 |
|
|
end
|
133 |
|
|
//////- ======== PR2 state, latch the data and wait for ACK going high
|
134 |
|
|
PR38B: begin
|
135 |
|
|
EnbB <= 1'b0; // no more force read enable for RAM
|
136 |
|
|
OPOvrRide <= 1'b1; // always output the data
|
137 |
|
|
cDQ <= 1'b1; // can request transfer now
|
138 |
|
|
if ((Phase3 == 1'b1) && (cDK == 1'b1)) begin
|
139 |
|
|
PSST <= PR20; // acknowledge so proceed
|
140 |
|
|
DTook <= cRd; // check if first data taken
|
141 |
|
|
end
|
142 |
|
|
end
|
143 |
|
|
//// ======= PS2 Reading the DMA RAM // loop here ===========================
|
144 |
|
|
PR20: begin
|
145 |
|
|
OPOvrRide <= 1'b0; // no need to force output data now
|
146 |
|
|
IncAddrB <= DTook; // data taken, rush data to output
|
147 |
|
|
if ((DTook == 1'b1) && (BBurstEnd == 1'b1)) begin // if currently pointing to last address and data taken
|
148 |
|
|
PSST <= PR32; // address will be inc past, so just goto last stage, output registers are all set already
|
149 |
|
|
end else begin
|
150 |
|
|
PSST <= PR21; // continue
|
151 |
|
|
end
|
152 |
|
|
end
|
153 |
|
|
PR21: begin
|
154 |
|
|
IncAddrB <= 1'b0; // no more address increment
|
155 |
|
|
EnbB <= DTook; // if data taken then update the Enb pulse correct phase enable pulse
|
156 |
|
|
PSST <= PR22;
|
157 |
|
|
end
|
158 |
|
|
PR22: begin
|
159 |
|
|
EnbB <= 1'b0; // RAM enable turn off after this cycle
|
160 |
|
|
cDQ <= cDQ & ~DTook; // keep request until first data taken cDQ will fall at end of Phase 2
|
161 |
|
|
PSST <= PR23;
|
162 |
|
|
end
|
163 |
|
|
PR23: begin
|
164 |
|
|
DTook <= cRd; // if read is asserted at phase 3, data was took
|
165 |
|
|
if (cDK == 1'b1) begin
|
166 |
|
|
PSST <= PR20;
|
167 |
|
|
end else begin
|
168 |
|
|
PSST <= PR37; // cDK gone unexpectedly
|
169 |
|
|
end
|
170 |
|
|
end
|
171 |
|
|
// if (DTaken == 1'b0) begin
|
172 |
|
|
// PSST <= PR01A; // data not taken, keep looping
|
173 |
|
|
// end else begin
|
174 |
|
|
// IncAddrB <= 1'b1; // data taken, new address
|
175 |
|
|
// if (BBurstEnd == 1'b1) begin // if currently pointing to last address and data taken
|
176 |
|
|
// PSST <= PR32; // go to last state, register must have been set
|
177 |
|
|
// end else begin
|
178 |
|
|
// PSST <= PR01A; // loop back
|
179 |
|
|
// end
|
180 |
|
|
// end
|
181 |
|
|
////- ======== PR32 state // last clock, cleaning the pipeline
|
182 |
|
|
PR32: begin // outputing the last data
|
183 |
|
|
IncAddrB <= 1'b0; // no more address increment
|
184 |
|
|
if (cDK == 1'b1) begin
|
185 |
|
|
PSST <= PR32;
|
186 |
|
|
end else begin
|
187 |
|
|
PSST <= PR37; // idle end
|
188 |
|
|
end
|
189 |
|
|
end
|
190 |
|
|
////- ======================= End of DMA loops ==========================
|
191 |
|
|
PR37: begin
|
192 |
|
|
if (WithinBBlock == 1'b1) begin
|
193 |
|
|
if (Phase3 == 1'b1) begin
|
194 |
|
|
PSST <= PR38; // loop back and do again
|
195 |
|
|
end else begin
|
196 |
|
|
PSST <= PR37;
|
197 |
|
|
end
|
198 |
|
|
end else begin
|
199 |
|
|
PSST <= PIdle; // block transferred go back to idle state
|
200 |
|
|
end
|
201 |
|
|
end
|
202 |
|
|
//////================== End of DMA Read loop ===========================
|
203 |
|
|
//////======== PS2 writing DMA RAM, PW40A =====================
|
204 |
|
|
PW40: begin
|
205 |
|
|
if ((Phase3 == 1'b1) && (cDK == 1'b1)) begin
|
206 |
|
|
PSST <= PW01A; // clock the state machine into correct phase
|
207 |
|
|
end
|
208 |
|
|
end
|
209 |
|
|
////////- =========== PW01A ====================================
|
210 |
|
|
PW01A: begin
|
211 |
|
|
IncAddrB <= 1'b0; // no more increment address
|
212 |
|
|
PSST <= PW01B;
|
213 |
|
|
end
|
214 |
|
|
PW01B: begin
|
215 |
|
|
DWrote <= DWrite; // a cleaner condition for testing
|
216 |
|
|
PSST <= PW01C;
|
217 |
|
|
end
|
218 |
|
|
PW01C: begin
|
219 |
|
|
EnbB <= DWrote; // enable write the RAM in the end of phase 3
|
220 |
|
|
WrB <= DWrote; // will write the RAM in phase 3
|
221 |
|
|
PSST <= PW01D;
|
222 |
|
|
end
|
223 |
|
|
PW01D: begin
|
224 |
|
|
EnbB <= 1'b0; // always turn off the RAM to conserve power
|
225 |
|
|
WrB <= 1'b0;
|
226 |
|
|
IncAddrB <= DWrote; // need to increment address if we have wrote anything last cycle
|
227 |
|
|
if (DWrote == 1'b1) begin // if last time we have written
|
228 |
|
|
if (BBurstEnd == 1'b1) begin // if address before increment is last for this burst
|
229 |
|
|
PSST <= PW32; // then we exit the loop for a while
|
230 |
|
|
end else begin
|
231 |
|
|
PSST <= PW01A; // else loop back
|
232 |
|
|
end
|
233 |
|
|
end else begin
|
234 |
|
|
PSST <= PW01A; // last time we have not written anything; loop again
|
235 |
|
|
end
|
236 |
|
|
end
|
237 |
|
|
////- ======== PW32 state, wait for 8 cycles and raise the CDREQ
|
238 |
|
|
PW32: begin
|
239 |
|
|
IncAddrB <= 1'b0; // clear the increment address
|
240 |
|
|
if (cDK == 1'b1) begin
|
241 |
|
|
PSST <= PW32; // loop back and wait until no more cDK
|
242 |
|
|
end else begin
|
243 |
|
|
PSST <= PW35;
|
244 |
|
|
end
|
245 |
|
|
end
|
246 |
|
|
//// ======== finish burst writing and cDK deassert, now check status of buffer
|
247 |
|
|
PW35: begin
|
248 |
|
|
if (Phase3 == 1'b1) begin
|
249 |
|
|
PSST <= PW36;
|
250 |
|
|
end
|
251 |
|
|
end
|
252 |
|
|
PW36: begin
|
253 |
|
|
if (WithinBBlock == 1'b1) begin
|
254 |
|
|
if (Phase3 == 1'b1) begin
|
255 |
|
|
PSST <= PW37; // skip and continue looping to write sector data
|
256 |
|
|
end else begin
|
257 |
|
|
PSST <= PW36; // loop here waiting
|
258 |
|
|
end
|
259 |
|
|
end else begin
|
260 |
|
|
PSST <= PIdle; //- lead out to Idle state
|
261 |
|
|
end
|
262 |
|
|
end
|
263 |
|
|
//// ============================================================
|
264 |
|
|
PW37: begin
|
265 |
|
|
if (Phase3 == 1'b1) begin
|
266 |
|
|
PSST <= PW38A;
|
267 |
|
|
end
|
268 |
|
|
end
|
269 |
|
|
//// =================================================================
|
270 |
|
|
PW38A: begin
|
271 |
|
|
PSST <= PW38B;
|
272 |
|
|
end
|
273 |
|
|
PW38B: begin
|
274 |
|
|
PSST <= PW38C;
|
275 |
|
|
end
|
276 |
|
|
PW38C: begin
|
277 |
|
|
cDQ <= 1'b1; // Raise the LREQ again at the falling edge of CLK
|
278 |
|
|
PSST <= PW38D;
|
279 |
|
|
end
|
280 |
|
|
PW38D: begin
|
281 |
|
|
PSST <= PW40; // loop again
|
282 |
|
|
end
|
283 |
|
|
////================== End of DMA Write loop ===========================
|
284 |
|
|
default: begin
|
285 |
|
|
PSST <= PIdle;
|
286 |
|
|
end
|
287 |
|
|
endcase
|
288 |
|
|
end // rising_edge(CLK4)
|
289 |
|
|
end
|
290 |
|
|
|
291 |
|
|
endmodule
|
292 |
|
|
|