OpenCores
URL https://opencores.org/ocsvn/ao486/ao486/trunk

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [soc/] [pc_dma/] [pc_dma.v] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright (c) 2014, Aleksander Osman
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * * Redistributions of source code must retain the above copyright notice, this
9
 *   list of conditions and the following disclaimer.
10
 *
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 *   this list of conditions and the following disclaimer in the documentation
13
 *   and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
 
27
module pc_dma(
28
    input               clk,
29
    input               rst_n,
30
 
31
    //000h - 00Fh for slave DMA
32
    input       [3:0]   slave_address,
33
    input               slave_read,
34
    output reg  [7:0]   slave_readdata,
35
    input               slave_write,
36
    input       [7:0]   slave_writedata,
37
 
38
    //080h - 08Fh for DMA page    
39
    input       [3:0]   page_address,
40
    input               page_read,
41
    output reg  [7:0]   page_readdata,
42
    input               page_write,
43
    input       [7:0]   page_writedata,
44
 
45
    //0C0h - 0DFh for master DMA
46
    input       [4:0]   master_address,
47
    input               master_read,
48
    output reg  [7:0]   master_readdata,
49
    input               master_write,
50
    input       [7:0]   master_writedata,
51
 
52
    //master
53
    output reg  [31:0]  avm_address,
54
    input               avm_waitrequest,
55
    output reg          avm_read,
56
    input               avm_readdatavalid,
57
    input       [7:0]   avm_readdata,
58
    output reg          avm_write,
59
    output reg  [7:0]   avm_writedata,
60
 
61
    //floppy 8-bit dma channel
62
    input               dma_floppy_req,
63
    output reg          dma_floppy_ack,
64
    output reg          dma_floppy_terminal,
65
    output reg  [7:0]   dma_floppy_readdata,
66
    input       [7:0]   dma_floppy_writedata,
67
 
68
    //soundblaster 8-bit dma channel
69
    input               dma_soundblaster_req,
70
    output reg          dma_soundblaster_ack,
71
    output reg          dma_soundblaster_terminal,
72
    output reg  [7:0]   dma_soundblaster_readdata,
73
    input       [7:0]   dma_soundblaster_writedata
74
);
75
 
76
//------------------------------------------------------------------------------
77
 
78
`define SDRAM_BASE      32'h08000000
79
 
80
//------------------------------------------------------------------------------
81
 
82
reg slave_read_last;
83
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) slave_read_last <= 1'b0; else if(slave_read_last) slave_read_last <= 1'b0; else slave_read_last <= slave_read; end
84
wire slave_read_valid = slave_read && slave_read_last == 1'b0;
85
 
86
//not needed: reg page_read_last;
87
 
88
reg master_read_last;
89
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) master_read_last <= 1'b0; else if(master_read_last) master_read_last <= 1'b0; else master_read_last <= master_read; end
90
wire master_read_valid = master_read && master_read_last == 1'b0;
91
 
92
//------------------------------------------------------------------------------
93
 
94
wire pag_extra_0_address =
95
    page_address == 4'h0 || page_address == 4'h4 || page_address == 4'h5 || page_address == 4'h6 ||
96
    page_address == 4'h8 || page_address == 4'hC || page_address == 4'hD || page_address == 4'hE;
97
 
98
reg [7:0] pag_extra_0;
99
always @(posedge clk or negedge rst_n) begin
100
    if(rst_n == 1'b0)                           pag_extra_0 <= 8'd0;
101
    else if(page_write && pag_extra_0_address)  pag_extra_0 <= page_writedata;
102
end
103
 
104
wire [7:0] pag_readdata_prepared =
105
    (page_address == 4'h1)?        sla_page_2 :
106
    (page_address == 4'h2)?        sla_page_3 :
107
    (page_address == 4'h3)?        sla_page_1 :
108
    (page_address == 4'h7)?        sla_page_0 :
109
    (page_address == 4'h9)?        mas_page_2 :
110
    (page_address == 4'hA)?        mas_page_3 :
111
    (page_address == 4'hB)?        mas_page_1 :
112
    (page_address == 4'hF)?        mas_page_0 :
113
                                   pag_extra_0;
114
 
115
always @(posedge clk or negedge rst_n) begin
116
    if(rst_n == 1'b0)   page_readdata <= 8'd0;
117
    else                page_readdata <= pag_readdata_prepared;
118
end
119
 
120
//------------------------------------------------------------------------------
121
 
122
reg [7:0] sla_page_0;
123
reg [7:0] sla_page_1;
124
reg [7:0] sla_page_2;
125
reg [7:0] sla_page_3;
126
 
127
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sla_page_0 <= 8'd0; else if(page_write && page_address == 4'h7) sla_page_0 <= page_writedata; end
128
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sla_page_1 <= 8'd0; else if(page_write && page_address == 4'h3) sla_page_1 <= page_writedata; end
129
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sla_page_2 <= 8'd0; else if(page_write && page_address == 4'h1) sla_page_2 <= page_writedata; end
130
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sla_page_3 <= 8'd0; else if(page_write && page_address == 4'h2) sla_page_3 <= page_writedata; end
131
 
132
reg [7:0] mas_page_0;
133
reg [7:0] mas_page_1;
134
reg [7:0] mas_page_2;
135
reg [7:0] mas_page_3;
136
 
137
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) mas_page_0 <= 8'd0; else if(page_write && page_address == 4'hF) mas_page_0 <= page_writedata; end
138
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) mas_page_1 <= 8'd0; else if(page_write && page_address == 4'hB) mas_page_1 <= page_writedata; end
139
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) mas_page_2 <= 8'd0; else if(page_write && page_address == 4'h9) mas_page_2 <= page_writedata; end
140
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) mas_page_3 <= 8'd0; else if(page_write && page_address == 4'hA) mas_page_3 <= page_writedata; end
141
 
142
 
143
//------------------------------------------------------------------------------
144
 
145
wire [7:0] sla_readdata_prepared =
146
    (slave_address == 4'h0 && sla_flip_flop == 1'b0)?    sla_current_address_0[7:0] :
147
    (slave_address == 4'h0 && sla_flip_flop == 1'b1)?    sla_current_address_0[15:8] :
148
    (slave_address == 4'h2 && sla_flip_flop == 1'b0)?    sla_current_address_1[7:0] :
149
    (slave_address == 4'h2 && sla_flip_flop == 1'b1)?    sla_current_address_1[15:8] :
150
    (slave_address == 4'h4 && sla_flip_flop == 1'b0)?    sla_current_address_2[7:0] :
151
    (slave_address == 4'h4 && sla_flip_flop == 1'b1)?    sla_current_address_2[15:8] :
152
    (slave_address == 4'h6 && sla_flip_flop == 1'b0)?    sla_current_address_3[7:0] :
153
    (slave_address == 4'h6 && sla_flip_flop == 1'b1)?    sla_current_address_3[15:8] :
154
 
155
    (slave_address == 4'h1 && sla_flip_flop == 1'b0)?    sla_current_counter_0[7:0] :
156
    (slave_address == 4'h1 && sla_flip_flop == 1'b1)?    sla_current_counter_0[15:8] :
157
    (slave_address == 4'h3 && sla_flip_flop == 1'b0)?    sla_current_counter_1[7:0] :
158
    (slave_address == 4'h3 && sla_flip_flop == 1'b1)?    sla_current_counter_1[15:8] :
159
    (slave_address == 4'h5 && sla_flip_flop == 1'b0)?    sla_current_counter_2[7:0] :
160
    (slave_address == 4'h5 && sla_flip_flop == 1'b1)?    sla_current_counter_2[15:8] :
161
    (slave_address == 4'h7 && sla_flip_flop == 1'b0)?    sla_current_counter_3[7:0] :
162
    (slave_address == 4'h7 && sla_flip_flop == 1'b1)?    sla_current_counter_3[15:8] :
163
 
164
    (slave_address == 4'h8)?                            { sla_pending, sla_terminated } :
165
 
166
    (slave_address == 4'hF)?                            { 4'hF, sla_mask } :
167
                                                        8'd0; //temp reg
168
 
169
always @(posedge clk or negedge rst_n) begin
170
    if(rst_n == 1'b0)   slave_readdata <= 8'd0;
171
    else                slave_readdata <= sla_readdata_prepared;
172
end
173
 
174
wire sla_reset = slave_write && slave_address == 4'hD;
175
 
176
wire sla_flop_flop_flip = (slave_read_valid || slave_write) && (slave_address <= 4'h7);
177
 
178
reg sla_flip_flop;
179
always @(posedge clk or negedge rst_n) begin
180
    if(rst_n == 1'b0)                               sla_flip_flop <= 1'b0;
181
    else if(sla_reset)                              sla_flip_flop <= 1'b0;
182
    else if(slave_write && slave_address == 4'hC)   sla_flip_flop <= 1'b0;
183
    else if(sla_flop_flop_flip)                     sla_flip_flop <= ~(sla_flip_flop);
184
end
185
 
186
reg [15:0] sla_base_address_1;
187
reg [15:0] sla_base_address_2;
188
 
189
always @(posedge clk or negedge rst_n) begin
190
    if(rst_n == 1'b0) sla_base_address_1 <= 16'd0;
191
    else if(slave_write && slave_address == 4'h2 && sla_flip_flop == 1'b0)  sla_base_address_1 <= { sla_base_address_1[15:8], slave_writedata };
192
    else if(slave_write && slave_address == 4'h2 && sla_flip_flop == 1'b1)  sla_base_address_1 <= { slave_writedata, sla_base_address_1[7:0] };
193
end
194
always @(posedge clk or negedge rst_n) begin
195
    if(rst_n == 1'b0) sla_base_address_2 <= 16'd0;
196
    else if(slave_write && slave_address == 4'h4 && sla_flip_flop == 1'b0)  sla_base_address_2 <= { sla_base_address_2[15:8], slave_writedata };
197
    else if(slave_write && slave_address == 4'h4 && sla_flip_flop == 1'b1)  sla_base_address_2 <= { slave_writedata, sla_base_address_2[7:0] };
198
end
199
 
200
reg [15:0] sla_current_address_0;
201
reg [15:0] sla_current_address_1;
202
reg [15:0] sla_current_address_2;
203
reg [15:0] sla_current_address_3;
204
 
205
always @(posedge clk or negedge rst_n) begin
206
    if(rst_n == 1'b0) sla_current_address_0 <= 16'd0;
207
    else if(slave_write && slave_address == 4'h0 && sla_flip_flop == 1'b0)  sla_current_address_0 <= { sla_current_address_0[15:8], slave_writedata };
208
    else if(slave_write && slave_address == 4'h0 && sla_flip_flop == 1'b1)  sla_current_address_0 <= { slave_writedata, sla_current_address_0[7:0] };
209
end
210
always @(posedge clk or negedge rst_n) begin
211
    if(rst_n == 1'b0) sla_current_address_1 <= 16'd0;
212
    else if(slave_write && slave_address == 4'h2 && sla_flip_flop == 1'b0)  sla_current_address_1 <= { sla_current_address_1[15:8], slave_writedata };
213
    else if(slave_write && slave_address == 4'h2 && sla_flip_flop == 1'b1)  sla_current_address_1 <= { slave_writedata, sla_current_address_1[7:0] };
214
 
215
    else if(dma_soundblaster_tc && sla_auto_1)         sla_current_address_1 <= sla_base_address_1;
216
    else if(dma_soundblaster_update && ~(sla_decrement_1))                  sla_current_address_1 <= sla_current_address_1 + 16'd1;
217
    else if(dma_soundblaster_update &&   sla_decrement_1)                   sla_current_address_1 <= sla_current_address_1 - 16'd1;
218
end
219
always @(posedge clk or negedge rst_n) begin
220
    if(rst_n == 1'b0) sla_current_address_2 <= 16'd0;
221
    else if(slave_write && slave_address == 4'h4 && sla_flip_flop == 1'b0)  sla_current_address_2 <= { sla_current_address_2[15:8], slave_writedata };
222
    else if(slave_write && slave_address == 4'h4 && sla_flip_flop == 1'b1)  sla_current_address_2 <= { slave_writedata, sla_current_address_2[7:0] };
223
 
224
    else if(dma_floppy_tc && sla_auto_2)    sla_current_address_2 <= sla_base_address_2;
225
 
226
    else if(dma_floppy_update && ~(sla_decrement_2))                        sla_current_address_2 <= sla_current_address_2 + 16'd1;
227
    else if(dma_floppy_update &&   sla_decrement_2)                         sla_current_address_2 <= sla_current_address_2 - 16'd1;
228
end
229
always @(posedge clk or negedge rst_n) begin
230
    if(rst_n == 1'b0) sla_current_address_3 <= 16'd0;
231
    else if(slave_write && slave_address == 4'h6 && sla_flip_flop == 1'b0)  sla_current_address_3 <= { sla_current_address_3[15:8], slave_writedata };
232
    else if(slave_write && slave_address == 4'h6 && sla_flip_flop == 1'b1)  sla_current_address_3 <= { slave_writedata, sla_current_address_3[7:0] };
233
end
234
 
235
reg [15:0] sla_base_counter_1;
236
reg [15:0] sla_base_counter_2;
237
 
238
always @(posedge clk or negedge rst_n) begin
239
    if(rst_n == 1'b0) sla_base_counter_1 <= 16'd0;
240
    else if(slave_write && slave_address == 4'h3 && sla_flip_flop == 1'b0)  sla_base_counter_1 <= { sla_base_counter_1[15:8], slave_writedata };
241
    else if(slave_write && slave_address == 4'h3 && sla_flip_flop == 1'b1)  sla_base_counter_1 <= { slave_writedata, sla_base_counter_1[7:0] };
242
end
243
always @(posedge clk or negedge rst_n) begin
244
    if(rst_n == 1'b0) sla_base_counter_2 <= 16'd0;
245
    else if(slave_write && slave_address == 4'h5 && sla_flip_flop == 1'b0)  sla_base_counter_2 <= { sla_base_counter_2[15:8], slave_writedata };
246
    else if(slave_write && slave_address == 4'h5 && sla_flip_flop == 1'b1)  sla_base_counter_2 <= { slave_writedata, sla_base_counter_2[7:0] };
247
end
248
 
249
reg [15:0] sla_current_counter_0;
250
reg [15:0] sla_current_counter_1;
251
reg [15:0] sla_current_counter_2;
252
reg [15:0] sla_current_counter_3;
253
 
254
always @(posedge clk or negedge rst_n) begin
255
    if(rst_n == 1'b0) sla_current_counter_0 <= 16'd0;
256
    else if(slave_write && slave_address == 4'h1 && sla_flip_flop == 1'b0)  sla_current_counter_0 <= { sla_current_counter_0[15:8], slave_writedata };
257
    else if(slave_write && slave_address == 4'h1 && sla_flip_flop == 1'b1)  sla_current_counter_0 <= { slave_writedata, sla_current_counter_0[7:0] };
258
end
259
always @(posedge clk or negedge rst_n) begin
260
    if(rst_n == 1'b0) sla_current_counter_1 <= 16'd0;
261
    else if(slave_write && slave_address == 4'h3 && sla_flip_flop == 1'b0)  sla_current_counter_1 <= { sla_current_counter_1[15:8], slave_writedata };
262
    else if(slave_write && slave_address == 4'h3 && sla_flip_flop == 1'b1)  sla_current_counter_1 <= { slave_writedata, sla_current_counter_1[7:0] };
263
 
264
    else if(dma_soundblaster_tc && sla_auto_1)                              sla_current_counter_1 <= sla_base_counter_1;
265
    else if(dma_soundblaster_update)                                        sla_current_counter_1 <= sla_current_counter_1 - 16'd1;
266
end
267
always @(posedge clk or negedge rst_n) begin
268
    if(rst_n == 1'b0) sla_current_counter_2 <= 16'd0;
269
    else if(slave_write && slave_address == 4'h5 && sla_flip_flop == 1'b0)  sla_current_counter_2 <= { sla_current_counter_2[15:8], slave_writedata };
270
    else if(slave_write && slave_address == 4'h5 && sla_flip_flop == 1'b1)  sla_current_counter_2 <= { slave_writedata, sla_current_counter_2[7:0] };
271
 
272
    else if(dma_floppy_tc && sla_auto_2)    sla_current_counter_2 <= sla_base_counter_2;
273
    else if(dma_floppy_update)                                              sla_current_counter_2 <= sla_current_counter_2 - 16'd1;
274
end
275
always @(posedge clk or negedge rst_n) begin
276
    if(rst_n == 1'b0)   sla_current_counter_3 <= 16'd0;
277
    else if(slave_write && slave_address == 4'h7 && sla_flip_flop == 1'b0)  sla_current_counter_3 <= { sla_current_counter_3[15:8], slave_writedata };
278
    else if(slave_write && slave_address == 4'h7 && sla_flip_flop == 1'b1)  sla_current_counter_3 <= { slave_writedata, sla_current_counter_3[7:0] };
279
end
280
 
281
reg sla_disabled;
282
always @(posedge clk or negedge rst_n) begin
283
    if(rst_n == 1'b0)   sla_disabled <= 1'b0;
284
    else if(sla_reset)  sla_disabled <= 1'b0;
285
    else if(slave_write && slave_address == 4'h8) sla_disabled <= slave_writedata[2];
286
end
287
 
288
wire [3:0] sla_writedata_bits =
289
    (slave_writedata[1:0] == 2'd0)?     4'b0001 :
290
    (slave_writedata[1:0] == 2'd1)?     4'b0010 :
291
    (slave_writedata[1:0] == 2'd2)?     4'b0100 :
292
                                        4'b1000;
293
 
294
wire [3:0] sla_pending_next =
295
    { sla_pending[3], dma_floppy_req | dma_floppy_state != 3'd0, dma_soundblaster_req | dma_soundblaster_state != 3'd0, sla_pending[0] };
296
 
297
reg [3:0] sla_pending;
298
always @(posedge clk or negedge rst_n) begin
299
    if(rst_n == 1'b0)   sla_pending <= 4'd0;
300
    else if(sla_reset)  sla_pending <= 4'd0;
301
    else if(slave_write && slave_address == 4'h9 && slave_writedata[2])     sla_pending <= sla_pending | sla_writedata_bits;
302
    else if(slave_write && slave_address == 4'h9 && ~(slave_writedata[2]))  sla_pending <= sla_pending & ~(sla_writedata_bits);
303
    else                                                                    sla_pending <= sla_pending_next;
304
end
305
 
306
reg [3:0] sla_mask;
307
always @(posedge clk or negedge rst_n) begin
308
    if(rst_n == 1'b0)   sla_mask <= 4'hF;
309
    else if(sla_reset)  sla_mask <= 4'hF;
310
    else if(slave_write && slave_address == 4'hE)                           sla_mask <= 4'h0;
311
    else if(slave_write && slave_address == 4'hF)                           sla_mask <= slave_writedata[3:0];
312
    else if(slave_write && slave_address == 4'hA && slave_writedata[2])     sla_mask <= sla_mask | sla_writedata_bits;
313
    else if(slave_write && slave_address == 4'hA && ~(slave_writedata[2]))  sla_mask <= sla_mask & ~(sla_writedata_bits);
314
 
315
    else if(dma_soundblaster_tc && ~(sla_auto_1))    sla_mask <= sla_mask | 4'b0010;
316
    else if(dma_floppy_tc && ~(sla_auto_2))          sla_mask <= sla_mask | 4'b0100;
317
end
318
 
319
reg sla_decrement_1;
320
reg sla_decrement_2;
321
 
322
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sla_decrement_1 <= 1'd0; else if(slave_write && slave_address == 4'hB && slave_writedata[1:0] == 2'd1) sla_decrement_1 <= slave_writedata[5]; end
323
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sla_decrement_2 <= 1'd0; else if(slave_write && slave_address == 4'hB && slave_writedata[1:0] == 2'd2) sla_decrement_2 <= slave_writedata[5]; end
324
 
325
reg sla_auto_1;
326
reg sla_auto_2;
327
 
328
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sla_auto_1 <= 1'd0; else if(slave_write && slave_address == 4'hB && slave_writedata[1:0] == 2'd1) sla_auto_1 <= slave_writedata[4]; end
329
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sla_auto_2 <= 1'd0; else if(slave_write && slave_address == 4'hB && slave_writedata[1:0] == 2'd2) sla_auto_2 <= slave_writedata[4]; end
330
 
331
reg [1:0] sla_transfer_1;
332
reg [1:0] sla_transfer_2;
333
 
334
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sla_transfer_1 <= 2'd0; else if(slave_write && slave_address == 4'hB && slave_writedata[1:0] == 2'd1) sla_transfer_1 <= slave_writedata[3:2]; end
335
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sla_transfer_2 <= 2'd0; else if(slave_write && slave_address == 4'hB && slave_writedata[1:0] == 2'd2) sla_transfer_2 <= slave_writedata[3:2]; end
336
 
337
reg [3:0] sla_terminated;
338
always @(posedge clk or negedge rst_n) begin
339
    if(rst_n == 1'b0)                                   sla_terminated <= 4'h0;
340
    else if(sla_reset)                                  sla_terminated <= 4'h0;
341
    else if(slave_read_valid && slave_address == 4'h8)  sla_terminated <= 4'd0;
342
    else if(dma_soundblaster_tc)                        sla_terminated <= sla_terminated | 4'b0010;
343
    else if(dma_floppy_tc)                              sla_terminated <= sla_terminated | 4'b0100;
344
end
345
 
346
//0: idle
347
//1: prepare read avm (goto 2) or write avm (goto 6)
348
 
349
//2: read avm until ~(waitrequest); goto 3
350
//3: read avm until readdatavalid; goto 4
351
 
352
//4: ack; update address; update counter (1 cycle); if tc goto 0
353
//5: wait for dma_req; goto 1
354
 
355
//6: write avm unit ~(waitrequest); goto 4
356
 
357
//7: verify or illegal transfer type
358
 
359
wire dma_floppy_update = dma_floppy_state == 3'd4;
360
wire dma_floppy_tc     = dma_floppy_update && sla_current_counter_2 == 16'h0000;
361
 
362
wire dma_soundblaster_update = dma_soundblaster_state == 3'd4;
363
wire dma_soundblaster_tc     = dma_soundblaster_update && sla_current_counter_1 == 16'h0000;
364
 
365
wire dma_floppy_start       = sla_disabled == 1'b0 && dma_floppy_state == 3'd0 && dma_soundblaster_state == 3'd0 && sla_pending[2] && ~(sla_mask[2]) && (sla_pending[1] == 1'b0 || sla_mask[1]);
366
wire dma_soundblaster_start = sla_disabled == 1'b0 && dma_floppy_state == 3'd0 && dma_soundblaster_state == 3'd0 && sla_pending[1] && ~(sla_mask[1]);
367
 
368
always @(posedge clk or negedge rst_n) begin
369
    if(rst_n == 1'b0)                                   dma_floppy_terminal <= 1'b0;
370
    else if(dma_floppy_state == 3'd4 && dma_floppy_tc)  dma_floppy_terminal <= 1'b1;
371
    else                                                dma_floppy_terminal <= 1'b0;
372
end
373
always @(posedge clk or negedge rst_n) begin
374
    if(rst_n == 1'b0)                                               dma_soundblaster_terminal <= 1'b0;
375
    else if(dma_soundblaster_state == 3'd4 && dma_soundblaster_tc)  dma_soundblaster_terminal <= 1'b1;
376
    else                                                            dma_soundblaster_terminal <= 1'b0;
377
end
378
 
379
reg [2:0] dma_floppy_state;
380
always @(posedge clk or negedge rst_n) begin
381
    if(rst_n == 1'b0)   dma_floppy_state <= 3'd0;
382
    else if(sla_reset)  dma_floppy_state <= 3'd0;
383
 
384
    else if(~(mas_not_ready) && dma_floppy_start)                   dma_floppy_state <= 3'd1;
385
 
386
    else if(dma_floppy_state == 3'd1 && sla_transfer_2 == 2'd2)     dma_floppy_state <= 3'd2; //read avm
387
    else if(dma_floppy_state == 3'd2 && avm_waitrequest == 1'b0)    dma_floppy_state <= 3'd3;
388
    else if(dma_floppy_state == 3'd3 && avm_readdatavalid)          dma_floppy_state <= 3'd4;
389
 
390
    else if(dma_floppy_state == 3'd4 && dma_floppy_tc)              dma_floppy_state <= 3'd0;
391
    else if(dma_floppy_state == 3'd4 && ~(dma_floppy_tc))           dma_floppy_state <= 3'd5;
392
    else if(dma_floppy_state == 3'd5 && dma_floppy_req)             dma_floppy_state <= 3'd1;
393
 
394
    else if(dma_floppy_state == 3'd1 && sla_transfer_2 == 2'd1)     dma_floppy_state <= 3'd6; //write avm
395
    else if(dma_floppy_state == 3'd6 && avm_waitrequest == 1'b0)    dma_floppy_state <= 3'd4;
396
 
397
    else if(dma_floppy_state == 3'd1)                               dma_floppy_state <= 3'd7; //verify or illegal transfer type
398
    else if(dma_floppy_state == 3'd7)                               dma_floppy_state <= 3'd4;
399
end
400
 
401
reg [2:0] dma_soundblaster_state;
402
always @(posedge clk or negedge rst_n) begin
403
    if(rst_n == 1'b0)   dma_soundblaster_state <= 3'd0;
404
    else if(sla_reset)  dma_soundblaster_state <= 3'd0;
405
 
406
    else if(~(mas_not_ready) && dma_soundblaster_start)                 dma_soundblaster_state <= 3'd1;
407
 
408
    else if(dma_soundblaster_state == 3'd1 && sla_transfer_1 == 2'd2)   dma_soundblaster_state <= 3'd2; //read avm
409
    else if(dma_soundblaster_state == 3'd2 && avm_waitrequest == 1'b0)  dma_soundblaster_state <= 3'd3;
410
    else if(dma_soundblaster_state == 3'd3 && avm_readdatavalid)        dma_soundblaster_state <= 3'd4;
411
 
412
    else if(dma_soundblaster_state == 3'd4 && dma_soundblaster_tc)      dma_soundblaster_state <= 3'd0;
413
    else if(dma_soundblaster_state == 3'd4 && ~(dma_soundblaster_tc))   dma_soundblaster_state <= 3'd5;
414
    else if(dma_soundblaster_state == 3'd5 && dma_soundblaster_req)     dma_soundblaster_state <= 3'd1;
415
 
416
    else if(dma_soundblaster_state == 3'd1 && sla_transfer_1 == 2'd1)   dma_soundblaster_state <= 3'd6; //write avm
417
    else if(dma_soundblaster_state == 3'd6 && avm_waitrequest == 1'b0)  dma_soundblaster_state <= 3'd4;
418
 
419
    else if(dma_soundblaster_state == 3'd1)                             dma_soundblaster_state <= 3'd7; //verify or illegal transfer type
420
    else if(dma_soundblaster_state == 3'd7)                             dma_soundblaster_state <= 3'd4;
421
end
422
 
423
always @(posedge clk or negedge rst_n) begin
424
    if(rst_n == 1'b0)                                           dma_floppy_ack <= 1'd0;
425
     else if(dma_floppy_state == 3'd3 && avm_readdatavalid)     dma_floppy_ack <= 1'b1;
426
     else if(dma_floppy_state == 3'd6 && ~(avm_waitrequest))    dma_floppy_ack <= 1'b1;
427
     else if(dma_floppy_state == 3'd7)                          dma_floppy_ack <= 1'b1;
428
     else                                                       dma_floppy_ack <= 1'b0;
429
end
430
 
431
always @(posedge clk or negedge rst_n) begin
432
    if(rst_n == 1'b0)                                               dma_soundblaster_ack <= 1'd0;
433
    else if(dma_soundblaster_state == 3'd3 && avm_readdatavalid)    dma_soundblaster_ack <= 1'b1;
434
    else if(dma_soundblaster_state == 3'd6 && ~(avm_waitrequest))   dma_soundblaster_ack <= 1'b1;
435
    else if(dma_soundblaster_state == 3'd7)                         dma_soundblaster_ack <= 1'b1;
436
    else                                                            dma_soundblaster_ack <= 1'b0;
437
end
438
 
439
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) dma_floppy_readdata       <= 8'd0; else if(avm_readdatavalid) dma_floppy_readdata       <= avm_readdata; end
440
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) dma_soundblaster_readdata <= 8'd0; else if(avm_readdatavalid) dma_soundblaster_readdata <= avm_readdata; end
441
 
442
//------------------------------------------------------------------------------
443
 
444
always @(posedge clk or negedge rst_n) begin
445
    if(rst_n == 1'b0)                       avm_address <= `SDRAM_BASE | 32'd0;
446
    else if(dma_soundblaster_state == 3'd1) avm_address <= `SDRAM_BASE | { 8'd0, sla_page_1, sla_current_address_1 };
447
    else if(dma_floppy_state == 3'd1)       avm_address <= `SDRAM_BASE | { 8'd0, sla_page_2, sla_current_address_2 };
448
end
449
 
450
 
451
always @(posedge clk or negedge rst_n) begin
452
    if(rst_n == 1'b0)   avm_read <= 1'd0;
453
 
454
    else if(dma_soundblaster_state == 3'd1 && sla_transfer_1 == 2'd2)   avm_read <= 1'b1;
455
    else if(dma_soundblaster_state == 3'd2 && avm_waitrequest == 1'b0)  avm_read <= 1'b0;
456
 
457
    else if(dma_floppy_state == 3'd1 && sla_transfer_2 == 2'd2)         avm_read <= 1'b1;
458
    else if(dma_floppy_state == 3'd2 && avm_waitrequest == 1'b0)        avm_read <= 1'b0;
459
end
460
 
461
always @(posedge clk or negedge rst_n) begin
462
    if(rst_n == 1'b0)   avm_write <= 1'd0;
463
 
464
    else if(dma_soundblaster_state == 3'd1 && sla_transfer_1 == 2'd1)   avm_write <= 1'b1;
465
    else if(dma_soundblaster_state == 3'd6 && avm_waitrequest == 1'b0)  avm_write <= 1'b0;
466
 
467
    else if(dma_floppy_state == 3'd1 && sla_transfer_2 == 2'd1)         avm_write <= 1'b1;
468
    else if(dma_floppy_state == 3'd6 && avm_waitrequest == 1'b0)        avm_write <= 1'b0;
469
end
470
 
471
always @(posedge clk or negedge rst_n) begin
472
    if(rst_n == 1'b0)                                                   avm_writedata <= 8'd0;
473
    else if(dma_soundblaster_state == 3'd1 && sla_transfer_1 == 2'd1)   avm_writedata <= dma_soundblaster_writedata;
474
    else if(dma_floppy_state == 3'd1 && sla_transfer_2 == 2'd1)         avm_writedata <= dma_floppy_writedata;
475
end
476
 
477
//------------------------------------------------------------------------------
478
//------------------------------------------------------------------------------
479
//------------------------------------------------------------------------------
480
 
481
wire [7:0] mas_readdata_prepared =
482
    (master_address == 5'h00 && mas_flip_flop == 1'b0)?     mas_current_address_0[7:0] :
483
    (master_address == 5'h00 && mas_flip_flop == 1'b1)?     mas_current_address_0[15:8] :
484
    (master_address == 5'h04 && mas_flip_flop == 1'b0)?     mas_current_address_1[7:0] :
485
    (master_address == 5'h04 && mas_flip_flop == 1'b1)?     mas_current_address_1[15:8] :
486
    (master_address == 5'h08 && mas_flip_flop == 1'b0)?     mas_current_address_2[7:0] :
487
    (master_address == 5'h08 && mas_flip_flop == 1'b1)?     mas_current_address_2[15:8] :
488
    (master_address == 5'h0C && mas_flip_flop == 1'b0)?     mas_current_address_3[7:0] :
489
    (master_address == 5'h0C && mas_flip_flop == 1'b1)?     mas_current_address_3[15:8] :
490
 
491
    (master_address == 5'h02 && mas_flip_flop == 1'b0)?     mas_current_counter_0[7:0] :
492
    (master_address == 5'h02 && mas_flip_flop == 1'b1)?     mas_current_counter_0[15:8] :
493
    (master_address == 5'h06 && mas_flip_flop == 1'b0)?     mas_current_counter_1[7:0] :
494
    (master_address == 5'h06 && mas_flip_flop == 1'b1)?     mas_current_counter_1[15:8] :
495
    (master_address == 5'h0A && mas_flip_flop == 1'b0)?     mas_current_counter_2[7:0] :
496
    (master_address == 5'h0A && mas_flip_flop == 1'b1)?     mas_current_counter_2[15:8] :
497
    (master_address == 5'h0E && mas_flip_flop == 1'b0)?     mas_current_counter_3[7:0] :
498
    (master_address == 5'h0E && mas_flip_flop == 1'b1)?     mas_current_counter_3[15:8] :
499
 
500
    (master_address == 5'h10)?                              { mas_pending, 4'd0 } :
501
 
502
    (master_address == 5'h1E)?                              { 4'hF, mas_mask } :
503
                                                            8'd0; //temp reg
504
 
505
always @(posedge clk or negedge rst_n) begin
506
    if(rst_n == 1'b0)   master_readdata <= 8'd0;
507
    else                master_readdata <= mas_readdata_prepared;
508
end
509
 
510
wire mas_reset = master_write && master_address == 5'h1A;
511
 
512
wire mas_flop_flop_flip = (master_read_valid || master_write) && master_address[0] == 1'b0 && (master_address <= 5'h0E);
513
 
514
reg mas_flip_flop;
515
always @(posedge clk or negedge rst_n) begin
516
    if(rst_n == 1'b0)                                   mas_flip_flop <= 1'b0;
517
    else if(mas_reset)                                  mas_flip_flop <= 1'b0;
518
    else if(master_write && master_address == 5'h18)    mas_flip_flop <= 1'b0;
519
    else if(mas_flop_flop_flip)                         mas_flip_flop <= ~(mas_flip_flop);
520
end
521
 
522
reg [15:0] mas_current_address_0;
523
reg [15:0] mas_current_address_1;
524
reg [15:0] mas_current_address_2;
525
reg [15:0] mas_current_address_3;
526
 
527
always @(posedge clk or negedge rst_n) begin
528
    if(rst_n == 1'b0) mas_current_address_0 <= 16'd0;
529
    else if(master_write && master_address == 5'h00 && mas_flip_flop == 1'b0)  mas_current_address_0 <= { mas_current_address_0[15:8], master_writedata };
530
    else if(master_write && master_address == 5'h00 && mas_flip_flop == 1'b1)  mas_current_address_0 <= { master_writedata, mas_current_address_0[7:0] };
531
end
532
always @(posedge clk or negedge rst_n) begin
533
    if(rst_n == 1'b0) mas_current_address_1 <= 16'd0;
534
    else if(master_write && master_address == 5'h04 && mas_flip_flop == 1'b0)  mas_current_address_1 <= { mas_current_address_1[15:8], master_writedata };
535
    else if(master_write && master_address == 5'h04 && mas_flip_flop == 1'b1)  mas_current_address_1 <= { master_writedata, mas_current_address_1[7:0] };
536
end
537
always @(posedge clk or negedge rst_n) begin
538
    if(rst_n == 1'b0) mas_current_address_2 <= 16'd0;
539
    else if(master_write && master_address == 5'h08 && mas_flip_flop == 1'b0)  mas_current_address_2 <= { mas_current_address_2[15:8], master_writedata };
540
    else if(master_write && master_address == 5'h08 && mas_flip_flop == 1'b1)  mas_current_address_2 <= { master_writedata, mas_current_address_2[7:0] };
541
end
542
always @(posedge clk or negedge rst_n) begin
543
    if(rst_n == 1'b0) mas_current_address_3 <= 16'd0;
544
    else if(master_write && master_address == 5'h0C && mas_flip_flop == 1'b0)  mas_current_address_3 <= { mas_current_address_3[15:8], master_writedata };
545
    else if(master_write && master_address == 5'h0C && mas_flip_flop == 1'b1)  mas_current_address_3 <= { master_writedata, mas_current_address_3[7:0] };
546
end
547
 
548
reg [15:0] mas_current_counter_0;
549
reg [15:0] mas_current_counter_1;
550
reg [15:0] mas_current_counter_2;
551
reg [15:0] mas_current_counter_3;
552
 
553
always @(posedge clk or negedge rst_n) begin
554
    if(rst_n == 1'b0) mas_current_counter_0 <= 16'd0;
555
    else if(master_write && master_address == 5'h02 && mas_flip_flop == 1'b0)  mas_current_counter_0 <= { mas_current_counter_0[15:8], master_writedata };
556
    else if(master_write && master_address == 5'h02 && mas_flip_flop == 1'b1)  mas_current_counter_0 <= { master_writedata, mas_current_counter_0[7:0] };
557
end
558
always @(posedge clk or negedge rst_n) begin
559
    if(rst_n == 1'b0) mas_current_counter_1 <= 16'd0;
560
    else if(master_write && master_address == 5'h06 && mas_flip_flop == 1'b0)  mas_current_counter_1 <= { mas_current_counter_1[15:8], master_writedata };
561
    else if(master_write && master_address == 5'h06 && mas_flip_flop == 1'b1)  mas_current_counter_1 <= { master_writedata, mas_current_counter_1[7:0] };
562
end
563
always @(posedge clk or negedge rst_n) begin
564
    if(rst_n == 1'b0) mas_current_counter_2 <= 16'd0;
565
    else if(master_write && master_address == 5'h0A && mas_flip_flop == 1'b0)  mas_current_counter_2 <= { mas_current_counter_2[15:8], master_writedata };
566
    else if(master_write && master_address == 5'h0A && mas_flip_flop == 1'b1)  mas_current_counter_2 <= { master_writedata, mas_current_counter_2[7:0] };
567
end
568
always @(posedge clk or negedge rst_n) begin
569
    if(rst_n == 1'b0)   mas_current_counter_3 <= 16'd0;
570
    else if(master_write && master_address == 5'h0E && mas_flip_flop == 1'b0)  mas_current_counter_3 <= { mas_current_counter_3[15:8], master_writedata };
571
    else if(master_write && master_address == 5'h0E && mas_flip_flop == 1'b1)  mas_current_counter_3 <= { master_writedata, mas_current_counter_3[7:0] };
572
end
573
 
574
reg mas_disabled;
575
always @(posedge clk or negedge rst_n) begin
576
    if(rst_n == 1'b0)                                   mas_disabled <= 1'b0;
577
    else if(mas_reset)                                  mas_disabled <= 1'b0;
578
    else if(master_write && master_address == 5'h10)    mas_disabled <= master_writedata[2];
579
end
580
 
581
wire [3:0] mas_writedata_bits =
582
    (master_writedata[1:0] == 2'd0)?    4'b0001 :
583
    (master_writedata[1:0] == 2'd1)?    4'b0010 :
584
    (master_writedata[1:0] == 2'd2)?    4'b0100 :
585
                                        4'b1000;
586
 
587
wire [3:0] mas_pending_next =
588
    { mas_pending[3:1], dma_floppy_start || dma_soundblaster_start || dma_floppy_state != 3'd0 || dma_soundblaster_state != 3'd0 };
589
 
590
reg [3:0] mas_pending;
591
always @(posedge clk or negedge rst_n) begin
592
    if(rst_n == 1'b0)   mas_pending <= 4'd0;
593
    else if(mas_reset)  mas_pending <= 4'd0;
594
    else if(master_write && master_address == 5'h12 && master_writedata[2])     mas_pending <= mas_pending | mas_writedata_bits;
595
    else if(master_write && master_address == 5'h12 && ~(master_writedata[2]))  mas_pending <= mas_pending & ~(mas_writedata_bits);
596
    else                                                                        mas_pending <= mas_pending_next;
597
end
598
 
599
reg [3:0] mas_mask;
600
always @(posedge clk or negedge rst_n) begin
601
    if(rst_n == 1'b0)   mas_mask <= 4'hF;
602
    else if(mas_reset)  mas_mask <= 4'hF;
603
    else if(master_write && master_address == 5'h1C)                            mas_mask <= 4'h0;
604
    else if(master_write && master_address == 5'h1E)                            mas_mask <= master_writedata[3:0];
605
    else if(master_write && master_address == 5'h14 && master_writedata[2])     mas_mask <= mas_mask | mas_writedata_bits;
606
    else if(master_write && master_address == 5'h14 && ~(master_writedata[2]))  mas_mask <= mas_mask & ~(mas_writedata_bits);
607
end
608
 
609
wire mas_not_ready = mas_disabled || mas_mask[0];
610
 
611
//------------------------------------------------------------------------------
612
 
613
// synthesis translate_off
614
wire _unused_ok = &{ 1'b0, page_read, 1'b0 };
615
// synthesis translate_on
616
 
617
//------------------------------------------------------------------------------
618
 
619
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.