📄 xmsmmc_core.v
字号:
// Copyright 2004-2005 Openchip// http://www.openchip.org`include "mmc_boot_defines.v"module xmsmmc_core( // CCLK From FPGA cclk, // Done From FPGA, indicates success done, // Init From FPGA (start of config and ERROR) init, // // MMC Card I/O // CS is not used tie up, pull up or leave open (not used) // DAT is directly connected to FPGA DIN(D0) // CMD Pin mmc_cmd, // CLK Pin mmc_clk, // Output enable control dis, // Error goes high if config error, or no MMC card inserted error );// global clock input, is divided to provide 400KHz and 20MHz Clocks input cclk;input init; // Pulse to start configinput done; //// error/status out, goes high on erroroutput error;// MMC Card I/O tristate when reset active and after config done/errorinout mmc_cmd;output mmc_clk;//input dis;// command data to MMC cardwire cmd_data_out;// "Transfer Mode" switch MMC clock to direct CCLK!wire mode_transfer;//// CMD1 Response Start Bit// if not Low, then no Card detected, error !wire cmd1_resp_start_bit;// CMD1 Response Busy Bit// if Low then busy, loop until goes highwire cmd1_resp_busy_bit;//// ASYNC reset we do not yet have clock!////wire int_reset;//assign int_reset = !init & !done;wire config_request;assign config_request = !init & !done;/*reg int_reset;always @(posedge cclk or posedge config_request) if (config_request) int_reset <= 1'b1; else int_reset <= 1'b0;*/wire int_reset;assign int_reset = config_request;// ---------------------------------------------------------------------------// Clock Prescaler// ---------------------------------------------------------------------------wire clk_mmc; mmc_boot_prescaler_16_1 precaler_i ( .rst ( int_reset ), .sys_clk( cclk ), .mmc_clk( clk_mmc ), .mode_transfer( mode_transfer ) );// command bit counterreg [7:0] counter_command_bits;always @(negedge clk_mmc or posedge int_reset) if (int_reset) counter_command_bits <= 8'b00000000; else counter_command_bits <= counter_command_bits + 8'b00000001;// ------------------------------------------------------------------//// ------------------------------------------------------------------// command sequencer state machinereg [3:0] cmd_state;reg [3:0] cmd_state_next;wire cmd_done;assign cmd_done = counter_command_bits == 8'b11111111;// CMD1 response Start (must be low if card is respondingassign cmd1_resp_start_bit = counter_command_bits[7:0] == 8'b00110101;// CMD1 response Busy bit (must be high if card is ready)assign cmd1_resp_busy_bit = counter_command_bits[7:0] == 8'b00111101;//// COMMAND State machine//always @(posedge clk_mmc or posedge int_reset) if (int_reset) cmd_state <= `CMD_INIT; else cmd_state <= cmd_state_next;// R1 48 bits// 00xx xxxx Sxxx xxxx ... xxx1// R2 136 bits !!// 00xx ... xxx1// R3 48 bit// 00xx ... xxx1always @(cmd_state, done, cmd_done, init, mmc_cmd, cmd1_resp_start_bit, cmd1_resp_busy_bit) begin cmd_state_next = cmd_state; case (cmd_state) // synopsys full_case parallel_case `CMD_INIT: // send 80+ clocks, then send CMD0 begin if (cmd_done & init) cmd_state_next = `CMD0; end `CMD0: // No response command, go send CMD1 begin if (cmd_done) cmd_state_next = `CMD1; end `CMD1: // send CMD1, loop until response bit31 is high begin // Response start detected ? // if not no card and go error if ( (cmd1_resp_start_bit==1'b1) & (mmc_cmd==1'b1) ) cmd_state_next = `CMD_CONFIG_ERROR; // if not busy advance to next // we can jump to next command as we are in the middle // of response time, so the next command will not // start before the last response has been read if ( (cmd1_resp_busy_bit==1'b1) & (mmc_cmd==1'b1) ) cmd_state_next = `CMD1_IDLE; end `CMD1_IDLE: // just some clocks spacing begin if (cmd_done) cmd_state_next = `CMD2; end `CMD2: // send CMD2 R2 begin if (cmd_done) cmd_state_next = `CMD3; end `CMD3: // send CMD3 R1 begin if (cmd_done) cmd_state_next = `CMD7; end `CMD7: // send CMD7 R1 begin if (cmd_done) cmd_state_next = `CMD11; end `CMD11: // send CMD11 R1 begin if (cmd_done) cmd_state_next = `CMD_TRANSFER; end // // Commands are sent, CMD is held high // MMC Card content is streamed out on DAT pin // `CMD_TRANSFER: begin if (done) cmd_state_next = `CMD_CONFIG_DONE; if (!init) cmd_state_next = `CMD_CONFIG_ERROR; end // Config done succesfully! `CMD_CONFIG_DONE: begin end // Some error has occoured `CMD_CONFIG_ERROR: begin end endcase end//// transfer mode, select high speed clock//assign mode_transfer = cmd_state == `CMD_TRANSFER;// ------------------------------------------------------------------//// Just emulating a memory to select CMD Data output//// ------------------------------------------------------------------wire cmd_bits;// mmc_cmd_select mmc_cmd_select_i ( .cmd( cmd_state ), .bit( counter_command_bits ), .cmd_active( cmd_bits ), .data( cmd_data_out ) );// ------------------------------------------------------------------//// ------------------------------------------------------------------assign mmc_cmd = (!dis & cmd_bits) ? cmd_data_out : 1'bz;assign mmc_clk = !dis ? (int_reset ? 1'b0 : clk_mmc) : 1'bz;// signal ERROR (active high)assign error = cmd_state == `CMD_CONFIG_ERROR;endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -