⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmsmmc_core.v

📁 MMC卡的VHDL源代码实现
💻 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 + -