-
Notifications
You must be signed in to change notification settings - Fork 9
/
ddr_controller.v
144 lines (138 loc) · 3.28 KB
/
ddr_controller.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
module ddr_controller(
output reg app_wdf_wren,
output reg [255:0] app_wdf_data,
output reg app_wdf_end,
output wire [26:0] app_addr,
output reg [2:0] app_cmd,
output reg app_en,
input app_rdy,
input app_wdf_rdy,
input [255:0] app_rd_data,
input app_rd_data_end,
input app_rd_data_valid,
input rst,
input clk,
input i_load,
input [26:0] i_ddr_strt_addr,
input [511:0] i_ddr_data,
input i_ddr_wr,
output reg o_ddr_wr_done,
input i_ddr_rd,
output reg [255:0] o_ddr_data,
output reg o_ddr_rd_data_valid,
output reg o_ddr_rd_done,
input i_config_buff_full
);
reg [2:0] state;
reg [26:0] ddr_wr_addr;
reg [26:0] ddr_rd_addr;
assign app_addr = app_cmd[0] ? ddr_rd_addr : ddr_wr_addr;
parameter idle = 'd0,
wr_data1 = 'd1,
wr_data2 = 'd2,
wr_cmd = 'd3,
wait1 = 'd4,
rd_cmd = 'd5,
rd_data1 = 'd6,
rd_data2 = 'd7;
always @(posedge clk)
begin
if(rst)
begin
state <= idle;
o_ddr_wr_done <= 1'b0;
app_wdf_wren <= 1'b0;
app_wdf_end <= 1'b0;
app_en <= 1'b0;
o_ddr_rd_done <= 1'b0;
o_ddr_rd_data_valid <= 1'b0;
end
else
begin
case(state)
idle:begin
o_ddr_rd_data_valid <= 1'b0;
if(i_load)
begin
ddr_rd_addr <= i_ddr_strt_addr;
ddr_wr_addr <= i_ddr_strt_addr;
end
else if(i_ddr_wr)
begin
state <= wr_data1;
app_wdf_wren <= 1'b1;
app_wdf_data <= i_ddr_data[255:0];
end
else if(i_ddr_rd & ~i_config_buff_full)
begin
state <= rd_cmd;
end
end
wr_data1:begin
if(app_wdf_rdy)
begin
app_wdf_data <= i_ddr_data[511:256];
state <= wr_data2;
app_wdf_end <= 1'b1;
end
end
wr_data2:begin
if(app_wdf_rdy)
begin
app_wdf_wren <= 1'b0;
app_wdf_end <= 1'b0;
state <= wr_cmd;
app_en <= 1'b1;
app_cmd <= 3'b000;
end
end
wr_cmd:begin
if(app_rdy)
begin
app_en <= 1'b0;
o_ddr_wr_done <= 1'b1;
state <= wait1;
ddr_wr_addr <= ddr_wr_addr + 64;
end
end
wait1:begin
state <= idle;
o_ddr_wr_done <= 1'b0;
o_ddr_rd_done <= 1'b0;
o_ddr_rd_data_valid <= 1'b0;
end
rd_cmd:begin
if(app_rdy)
begin
app_en <= 1'b1;
app_cmd <= 3'b001;
state <= rd_data1;
end
end
rd_data1:begin
app_en <= 1'b0;
if(app_rd_data_valid)
begin
o_ddr_data <= app_rd_data;
state <= rd_data2;
o_ddr_rd_data_valid <= 1'b1;
end
else
o_ddr_rd_data_valid <= 1'b0;
end
rd_data2:begin
if(app_rd_data_valid)
begin
o_ddr_data <= app_rd_data;
state <= wait1;
o_ddr_rd_done <= 1'b1;
o_ddr_rd_data_valid <= 1'b1;
ddr_rd_addr <= ddr_rd_addr + 64;
end
else
o_ddr_rd_data_valid <= 1'b0;
end
endcase
end
end
endmodule