-
Notifications
You must be signed in to change notification settings - Fork 0
/
sd_loader.v
125 lines (111 loc) · 4.27 KB
/
sd_loader.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
// modified by Laurentiu-Cristian Duca, 2023-09-12
// used to copy linux from microsd to ram
// adapted from https://github.com/WangXuan95/FPGA-SDcard-Reader
//--------------------------------------------------------------------------------------------------------
`include "define.vh"
module sd_loader (
input wire clk27mhz,
// rstn active-low, You can re-read SDcard by pushing the reset button.
input wire resetn,
input wire [2:0] w_main_init_state,
input wire [7:0] w_ctrl_state,
// when sdcard_pwr_n = 0, SDcard power on
output wire sdcard_pwr_n,
// signals connect to SD bus
output wire sdclk,
inout wire sdcmd,
input wire sddat0,
output wire sddat1, sddat2, sddat3,
output reg [31:0] DATA,
output reg WE,
output reg DONE
);
assign sdcard_pwr_n = 1'b0; // keep SDcard power-on
assign {sddat1, sddat2, sddat3} = 3'b111; // Must set sddat1~3 to 1 to avoid SD card from entering SPI mode
reg [31:0] waddr=0;
wire rdone;
reg rstart = 0;
reg [31:0] rsector = 0;
wire outen;
wire [7:0] outbyte;
`define SD_SECTOR_SIZE 512
reg [7:0] state=0;
reg [7:0] mem[0:`SD_SECTOR_SIZE - 1];
reg [$clog2(`SD_SECTOR_SIZE):0] i=0;
always @(posedge clk27mhz) begin
if(!resetn) begin
rstart <= 0;
rsector <= 0;
state <= 0;
DATA <= 0;
WE <= 0;
DONE <= 0;
i <= 0;
end else begin
if(state == 0) begin
if (DONE==0) begin
if(rdone) begin // sector was read
rstart <= 0;
state <= 20;
end else if(w_main_init_state == 3) begin
rstart <= 1;
end else
rstart <= 0;
end else
rstart <= 0;
end else if(state == 20) begin
if(w_ctrl_state == 0)
if((i < `SD_SECTOR_SIZE) && ((rsector << $clog2(`SD_SECTOR_SIZE))+i) < `BIN_SIZE) begin
DATA <= {mem[i+3], mem[i+2], mem[i+1], mem[i]};
WE <= 1;
i <= i + 4;
state <= 21;
end else begin
i <= 0;
state <= 0;
rsector <= rsector + 1;
if(waddr>=`BIN_SIZE)
DONE <= 1;
end
end else if(state == 21) begin
if(w_ctrl_state != 0) begin
WE <= 0;
state <= 20;
end
end
end
end
always @(posedge clk27mhz) begin
if(!resetn) begin
waddr <= 0;
end else begin
if(DONE==0 && outen && w_main_init_state == 3) begin
mem[waddr & (`SD_SECTOR_SIZE -1)] <= outbyte;
waddr <= waddr + 1;
end
end
end
wire [3:0] card_stat;
wire [1:0] card_type;
//----------------------------------------------------------------------------------------------------
// sd_reader
//----------------------------------------------------------------------------------------------------
sd_reader #(
.CLK_DIV ( 2 ) // because clk=27MHz, CLK_DIV must ≥2
) u_sd_reader (
.rstn ( resetn ),
.clk ( clk27mhz ),
.sdclk ( sdclk ),
.sdcmd ( sdcmd ),
.sddat0 ( sddat0 ),
.card_stat ( card_stat ), // show the sdcard initialize status
.card_type ( card_type ), // 0=UNKNOWN , 1=SDv1 , 2=SDv2 , 3=SDHCv2
.rstart ( rstart ),
.rsector ( rsector ), // read No. 0 sector (the first sector) in SDcard
.rbusy ( ),
.rdone ( rdone ),
.outen ( outen ),
.outaddr ( ),
.outbyte ( outbyte )
);
endmodule