-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdma.v
118 lines (95 loc) · 3.06 KB
/
dma.v
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
module dma(
input [7:0] dmaAdress,
input clock,
output DmaEnableSignal,
input [15:0] A_cpu,
input [7:0] Di_cpu,
output [7:0] Do_cpu,
input wr_cpu,
input rd_cpu,
output reg [15:0] A_oam,
output reg [7:0] Do_oam,
input [7:0] Di_oam,
output reg wr_oam,
output reg rd_oam,
output [15:0] A_mmu,
output [7:0] Do_mmu,
input [7:0] Di_mmu,
output wr_mmu,
output rd_mmu
);
reg [2:0] CurrentTCycle = 3'd0;
reg [7:0] DmaCounter = 8'b0;
reg [7:0] CurrentDMAAdress = 8'b0;
reg [1:0] DmaState = 2'b00; //00 wait for dma transfert, 01 init dma transfert, 10 dma transfert in progress
reg [15:0] A_dma = 16'b0;
reg [7:0] Do_dma = 8'b0;
reg wr_dma = 1'b0;
reg rd_dma = 1'b0;
assign DmaEnableSignal = DmaState == 2'b00 ? 1'b0 : 1'b1;
assign A_mmu = DmaState ? A_dma : A_cpu;
assign Do_mmu = DmaState ? Do_dma : Di_cpu;
assign wr_mmu = DmaState ? wr_dma : wr_cpu;
assign rd_mmu = DmaState ? rd_dma : rd_cpu;
assign Do_cpu = DmaState ? 8'b0 : Di_mmu;
always @(posedge clock) begin
if(dmaAdress != 8'b0) begin
DmaState <= 2'b01;
A_dma <= {dmaAdress, 8'b0};
rd_dma <= 1'b1;
DmaCounter <= 8'b0;
CurrentTCycle <= 3'd1;
A_oam <= 16'h0000;
CurrentDMAAdress <= dmaAdress;
end
else
if(DmaState == 2'b01) begin
case(CurrentTCycle)
3'd1: begin
CurrentTCycle <= CurrentTCycle + 3'd1;
end
3'd2: begin
CurrentTCycle <= CurrentTCycle + 3'd1;
end
3'd3: begin
CurrentTCycle <= 3'd0;
DmaState <= 2'b10;
end
endcase
end
else
if(DmaState == 2'b10) begin
case(CurrentTCycle)
3'd0: begin
Do_oam <= Di_mmu;
CurrentTCycle <= CurrentTCycle + 3'd1;
end
3'd1: begin
wr_oam <= 1'b1;
//rd_dma <= 1'b0;
CurrentTCycle <= CurrentTCycle + 3'd1;
end
3'd2: begin
wr_oam <= 1'b0;
A_dma <= {CurrentDMAAdress, DmaCounter + 1'b1};
//rd_dma <= 1'b1;
CurrentTCycle <= CurrentTCycle + 3'd1;
end
3'd3: begin
CurrentTCycle <= 3'd0;
if(DmaCounter == 8'd159)
begin
DmaCounter <= 8'd0;
DmaState <= 2'b00;
rd_dma <= 1'b0;
CurrentDMAAdress <= 8'b0;
end
else begin
A_oam <= 16'h0000 + {8'b0, DmaCounter + 1'b1};
DmaCounter <= DmaCounter + 1'b1;
end
end
endcase
end
end
endmodule