Subversion Repositories ngs

Rev

Rev 61 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 lvd 1
// part of NeoGS project
2
//
3
// (c) NedoPC 2007-2008
4
//
5
// modelling is in tb_dma1.*
6
// look also at dma_access.png
7
 
8
module dma_access(
9
 
10
        input            clk,
11
 
12
        input            rst_n,
13
 
14
 
15
        input            dma_req,  // DMA request
62 lvd 16
        input     [21:0] dma_addr, // DMA address (2mb)
2 lvd 17
        input            dma_rnw,  // DMA READ/nWRITE
18
        input      [7:0] dma_wd,   // DMA data to write
19
        output reg [7:0] dma_rd,   // DMA data just read
20
 
21
        output reg       dma_busynready, // DMA BUSY/nREADY
22
        output reg       dma_ack, // positive pulse as dma_busynready goes high
23
        output reg       dma_end, // positive pulse as dma_busynready goes low
24
 
25
        output wire        mem_dma_bus,  // DMA taking over the bus
62 lvd 26
        output wire [21:0] mem_dma_addr, // DMA address going to the bus
2 lvd 27
        output wire  [7:0] mem_dma_wd,   // DMA data going to the bus
28
        input        [7:0] mem_dma_rd,   // DMA data going from the bus
29
        output wire        mem_dma_rnw,  // DMA bus direction (1=read, 0=write)
30
        output reg         mem_dma_oe,   // DMA read strobe going to the bus
31
        output reg         mem_dma_we,   // DMA write pulse going to the bus
32
 
33
 
34
        output reg       busrq_n, // CPU       signals
35
        input            busak_n  //    control
36
);
37
 
38
        reg dma_bus;
39
 
62 lvd 40
        reg [21:0] int_dma_addr;
2 lvd 41
        reg        int_dma_rnw;
42
        reg  [7:0] int_dma_wd;
43
        wire [7:0] int_dma_rd;
44
 
45
        assign mem_dma_bus  = dma_bus;
46
        assign mem_dma_addr = int_dma_addr;
47
        assign mem_dma_wd   = int_dma_wd;
48
        assign mem_dma_rnw  = int_dma_rnw;
49
        assign int_dma_rd   = mem_dma_rd;
50
 
51
 
52
 
53
        localparam IDLE     = 0;
54
        localparam START    = 1;
55
        localparam WACK     = 2;
56
        localparam READ1    = 3;
57
        localparam READ2    = 4;
58
        localparam WRITE1   = 5;
59
        localparam WRITE2   = 6;
60
 
61
 
62
        reg [3:0] state;
63
        reg [3:0] next_state;
64
 
65
 
66
 
67
 
68
        // for simulation purposes
69
        initial
70
        begin
71
                state       <= IDLE;
72
                busrq_n     <= 1'b1;
73
                mem_dma_oe  <= 1'b1;
74
                mem_dma_we  <= 1'b1;
75
        end
76
 
77
 
78
// FSM
79
        always @(posedge clk, negedge rst_n)
80
        begin
81
                if( !rst_n )
82
                        state <= IDLE;
83
                else
84
                        state <= next_state;
85
        end
86
 
87
 
88
        always @*
89
        begin
90
                case( state )
91
//////////////////////////////////////////////////////////////////////////////////////////
92
                IDLE:
93
                begin
94
                        if( dma_req==1'b1 )
95
                                next_state <= START;
96
                        else
97
                                next_state <= IDLE;
98
                end
99
//////////////////////////////////////////////////////////////////////////////////////////
100
                START:
101
                begin
102
                        next_state <= WACK;
103
                end
104
//////////////////////////////////////////////////////////////////////////////////////////
105
                WACK:
106
                begin
107
                        if( busak_n == 1'b1 ) ///// ACHTUNG WARNING!!! probably use here registered busak?
108
                                next_state <= WACK;
109
                        else // busak_n == 1'b0
110
                        begin
111
                                if( int_dma_rnw == 1'b1 ) // read
112
                                        next_state <= READ1;
113
                                else // int_dma_rnw == 1'b0 - write
114
                                        next_state <= WRITE1;
115
                        end
116
                end
117
//////////////////////////////////////////////////////////////////////////////////////////
118
                READ1:
119
                begin
120
                        next_state <= READ2;
121
                end
122
//////////////////////////////////////////////////////////////////////////////////////////
123
                READ2:
124
                begin
125
                        if( dma_req == 1'b0 )
126
                                next_state <= IDLE;
127
                        else // dma_req == 1'b1
128
                        begin
129
                                if( dma_rnw == 1'b1 ) // next is read
130
                                        next_state <= READ1;
131
                                else // dma_rnw == 1'b0 - next is write
132
                                        next_state <= WRITE1;
133
                        end
134
                end
135
//////////////////////////////////////////////////////////////////////////////////////////
136
                WRITE1:
137
                begin
138
                        next_state <= WRITE2;
139
                end
140
//////////////////////////////////////////////////////////////////////////////////////////
141
                WRITE2:
142
                begin
143
                        if( dma_req == 1'b0 )
144
                                next_state <= IDLE;
145
                        else // dma_req == 1'b1
146
                        begin
147
                                if( dma_rnw == 1'b1 ) // next is read
148
                                        next_state <= READ1;
149
                                else // dma_rnw == 1'b0 - next is write
150
                                        next_state <= WRITE1;
151
                        end
152
                end
153
//////////////////////////////////////////////////////////////////////////////////////////
154
                endcase
155
        end
156
 
157
 
158
        always @(posedge clk, negedge rst_n)
159
        begin
160
                if( !rst_n )
161
                begin
162
                        busrq_n        <= 1'b1;
163
                        dma_busynready <= 1'b0;
164
                        dma_ack        <= 1'b0;
165
                        dma_end        <= 1'b0;
166
                        dma_bus        <= 1'b0;
167
                        mem_dma_oe     <= 1'b1;
168
                end
169
                else case( next_state )
170
//////////////////////////////////////////////////////////////////////////////////////////
171
                IDLE:
172
                begin
173
                        dma_end        <= 1'b0;
174
 
175
                        busrq_n        <= 1'b1;
176
                        dma_bus        <= 1'b0;
177
                        mem_dma_oe     <= 1'b1;
178
                end
179
//////////////////////////////////////////////////////////////////////////////////////////
180
                START:
181
                begin
182
//                      dma_bus        <= 1'b0; // if rst=0>1 and dma_ack=1 --> ??? is this really needed?
183
 
184
 
185
                        busrq_n        <= 1'b0;
186
 
187
                        dma_busynready <= 1'b1;
188
                        dma_ack        <= 1'b1;
189
 
190
                        int_dma_rnw    <= dma_rnw;
191
                        int_dma_addr   <= dma_addr;
192
                        int_dma_wd     <= dma_wd;
193
                end
194
//////////////////////////////////////////////////////////////////////////////////////////
195
                WACK:
196
                begin
197
                        dma_ack <= 1'b0;
198
                end
199
//////////////////////////////////////////////////////////////////////////////////////////
200
                READ1:
201
                begin
202
                        dma_bus    <= 1'b1; // take over the bus
203
                        mem_dma_oe <= 1'b0;
204
                        if( dma_busynready == 1'b0 ) // if we are here from READ2 or WRITE2
205
                        begin
206
                                dma_busynready <= 1'b1;
207
                                dma_ack        <= 1'b1;
208
                                dma_end        <= 1'b0;
209
                                int_dma_rnw    <= 1'b1;
210
                                int_dma_addr   <= dma_addr;
211
                        end
212
                end
213
//////////////////////////////////////////////////////////////////////////////////////////
214
                READ2:
215
                begin
216
                        dma_busynready <= 1'b0;
217
                        dma_ack        <= 1'b0;
218
                        dma_end        <= 1'b1;
219
                        dma_rd <= int_dma_rd;
220
                end
221
//////////////////////////////////////////////////////////////////////////////////////////
222
                WRITE1:
223
                begin
224
                        dma_bus    <= 1'b1; // take over the bus
225
                        mem_dma_oe <= 1'b1;
226
 
227
                        if( dma_busynready == 1'b0 ) // from READ2 or WRITE2
228
                        begin
229
                                dma_busynready <= 1'b1;
230
                                dma_ack        <= 1'b1;
231
                                dma_end        <= 1'b0;
232
                                int_dma_rnw    <= 1'b0;
233
                                int_dma_addr   <= dma_addr;
234
                                int_dma_wd     <= dma_wd;
235
                        end
236
                end
237
//////////////////////////////////////////////////////////////////////////////////////////
238
                WRITE2:
239
                begin
240
                        dma_busynready <= 1'b0;
241
                        dma_ack        <= 1'b0;
242
                        dma_end        <= 1'b1;
243
                end
244
//////////////////////////////////////////////////////////////////////////////////////////
245
                endcase
246
        end
247
 
248
 
249
 
250
 
251
// mem_dma_we generator
252
 
253
        always @(negedge clk,negedge rst_n)
254
        begin
255
                if( !rst_n )
256
                        mem_dma_we <= 1'b1;
257
                else
258
                begin
259
                        if( dma_bus )
260
                        begin
261
                                if( !int_dma_rnw )
262
                                        mem_dma_we <= ~mem_dma_we;
263
                        end
264
                        else
265
                                mem_dma_we <= 1'b1;
266
                end
267
        end
268
 
269
 
270
endmodule
271