forked from Github_Repos/cvw
		
	
		
			
				
	
	
		
			1117 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			Systemverilog
		
	
	
	
	
	
			
		
		
	
	
			1117 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			Systemverilog
		
	
	
	
	
	
//`include "timescale.v"
 | 
						|
//`timescale 1ps / 1ps
 | 
						|
`include "sd_defines.h"
 | 
						|
`define tTLH 10 //Clock rise time
 | 
						|
`define tHL 10 //Clock fall time
 | 
						|
`define tISU 6 //Input setup time
 | 
						|
`define tIH 0 //Input hold time
 | 
						|
`define tODL 14 //Output delay
 | 
						|
`define DLY_TO_OUTP 47 //47
 | 
						|
 | 
						|
`define BLOCKSIZE 512
 | 
						|
`define MEMSIZE 24643590 // 2mb block
 | 
						|
`define BLOCK_BUFFER_SIZE 1
 | 
						|
`define TIME_BUSY 512
 | 
						|
 | 
						|
`define PRG 7
 | 
						|
`define RCV 6
 | 
						|
`define DATAS 5
 | 
						|
`define TRAN 4
 | 
						|
 | 
						|
module    sdModel
 | 
						|
  (
 | 
						|
   input       sdClk,
 | 
						|
   inout tri1       cmd,
 | 
						|
   inout tri1 [3:0] dat
 | 
						|
   );
 | 
						|
   //parameter SD_FILE = "ramdisk2.hex";
 | 
						|
   
 | 
						|
   reg 	     oeCmd;
 | 
						|
   reg 	     oeDat;
 | 
						|
   reg 	     cmdOut;
 | 
						|
   reg [3:0] datOut;
 | 
						|
   reg [10:0] transf_cnt;
 | 
						|
   reg [10:0] BLOCK_WIDTH;
 | 
						|
 | 
						|
   reg [5:0]  lastCMD;
 | 
						|
   reg 	      cardIdentificationState;
 | 
						|
   reg 	      CardTransferActive;
 | 
						|
   reg [2:0]  BusWidth;
 | 
						|
 | 
						|
   assign cmd = oeCmd ? cmdOut : 1'bz;
 | 
						|
   assign dat = oeDat ? datOut : 4'bz;
 | 
						|
 | 
						|
   reg 	      InbuffStatus;
 | 
						|
   reg [32:0] ByteAddr;
 | 
						|
   reg [7:0]  Inbuff [0:511];
 | 
						|
   reg [7:0]  FLASHmem [logic[32:0]];
 | 
						|
   reg [7:0]  wide_data [0:63];
 | 
						|
   
 | 
						|
   
 | 
						|
 | 
						|
   reg [46:0] inCmd;
 | 
						|
   reg [5:0]  cmdRead;
 | 
						|
   reg [7:0]  cmdWrite;
 | 
						|
   reg 	      crcIn;
 | 
						|
   reg 	      crcEn;
 | 
						|
   reg 	      crcRst;
 | 
						|
   reg [31:0] CardStatus;
 | 
						|
   reg [15:0] RCA;
 | 
						|
   reg [31:0] OCR;
 | 
						|
   reg [120:0] CID;
 | 
						|
   reg [120:0] CSD;
 | 
						|
   reg 	       Busy; //0 when busy
 | 
						|
   wire [6:0]  crcOut;
 | 
						|
   reg [4:0]   crc_c;
 | 
						|
 | 
						|
   reg [3:0]   CurrentState; 
 | 
						|
   reg [3:0]   DataCurrentState;
 | 
						|
   
 | 
						|
`define RCASTART 16'h2000
 | 
						|
`define OCRSTART 32'h40ff8000 // SDHC
 | 
						|
`define STATUSSTART 32'h0
 | 
						|
`define CIDSTART 128'hffffffddddddddaaaaaaaa99999999  //Just some random data not really useful anyway 
 | 
						|
`define CSDSTART 128'hadaeeeddddddddaaaaaaaa12345678 
 | 
						|
 | 
						|
`define outDelay 4 
 | 
						|
   reg [2:0]   outDelayCnt;
 | 
						|
   reg [9:0]   flash_write_cnt;
 | 
						|
   reg [8:0]   flash_blockwrite_cnt;
 | 
						|
 | 
						|
   parameter SIZE = 10;
 | 
						|
   parameter CONTENT_SIZE = 40;
 | 
						|
   parameter 
 | 
						|
     IDLE   =  10'b0000_0000_01,
 | 
						|
     READ_CMD       =  10'b0000_0000_10,
 | 
						|
     ANALYZE_CMD    =  10'b0000_0001_00,
 | 
						|
     SEND_CMD	    =  10'b0000_0010_00;
 | 
						|
   reg [SIZE-1:0] state;
 | 
						|
   reg [SIZE-1:0] next_state;
 | 
						|
 | 
						|
   parameter 
 | 
						|
     DATA_IDLE   =10'b0000_0000_01,    
 | 
						|
     READ_WAITS  =10'b0000_0000_10,
 | 
						|
     READ_DATA   =10'b0000_0001_00,
 | 
						|
     WRITE_FLASH =10'b0000_0010_00,
 | 
						|
     WRITE_DATA  =10'b0000_0100_00;
 | 
						|
   parameter okcrctoken = 4'b0101;
 | 
						|
   parameter invalidcrctoken = 4'b1111;
 | 
						|
   reg [SIZE-1:0] dataState;
 | 
						|
   reg [SIZE-1:0] next_datastate;
 | 
						|
 | 
						|
   reg 		  ValidCmd;
 | 
						|
   reg 		  inValidCmd;
 | 
						|
 | 
						|
   reg [7:0] 	  response_S;
 | 
						|
   reg [135:0] 	  response_CMD;
 | 
						|
   integer 	  responseType;
 | 
						|
 | 
						|
   reg [9:0] 	  block_cnt;
 | 
						|
   reg 		  wptr;
 | 
						|
   reg 		  crc_ok;
 | 
						|
   reg [3:0] 	  last_din;
 | 
						|
   
 | 
						|
   reg 		  crcDat_rst;
 | 
						|
   reg 		  mult_read;
 | 
						|
   reg 		  mult_write;
 | 
						|
   reg 		  crcDat_en;
 | 
						|
   reg [3:0] 	  crcDat_in; 
 | 
						|
   wire [15:0] 	  crcDat_out [3:0];
 | 
						|
 | 
						|
   integer sdModel_file_desc;
 | 
						|
 | 
						|
   genvar 	  i;
 | 
						|
    for(i=0; i<4; i=i+1) begin:CRC_16_gen
 | 
						|
	  sd_crc_16 CRC_16_i (crcDat_in[i],crcDat_en, sdClk, crcDat_rst, crcDat_out[i]);
 | 
						|
    end
 | 
						|
   
 | 
						|
   sd_crc_7 crc_7
 | 
						|
     ( 
 | 
						|
       crcIn,
 | 
						|
       crcEn,
 | 
						|
       sdClk,
 | 
						|
       crcRst,
 | 
						|
       crcOut
 | 
						|
       );
 | 
						|
 | 
						|
   reg stop;
 | 
						|
 | 
						|
   reg appendCrc;
 | 
						|
   reg [31:0] startUppCnt;
 | 
						|
 | 
						|
   reg 	     q_start_bit;
 | 
						|
   
 | 
						|
   //Card initialization DAT contents
 | 
						|
   //initial $readmemh(SD_FILE, FLASHmem);
 | 
						|
 | 
						|
   initial begin
 | 
						|
      wide_data[0] <= 'h00;
 | 
						|
      wide_data[1] <= 'hc8;
 | 
						|
      wide_data[2] <= 'h80;
 | 
						|
      wide_data[3] <= 'h01;
 | 
						|
      wide_data[4] <= 'h80;
 | 
						|
      wide_data[5] <= 'h01;
 | 
						|
      wide_data[6] <= 'h80;
 | 
						|
      wide_data[7] <= 'h01;
 | 
						|
      wide_data[8] <= 'h80;
 | 
						|
      wide_data[9] <= 'h01;
 | 
						|
      wide_data[10] <= 'hc0;
 | 
						|
      wide_data[11] <= 'h01;
 | 
						|
      wide_data[12] <= 'h80;
 | 
						|
      wide_data[13] <= 'h03;
 | 
						|
      wide_data[14] <= 'h00;
 | 
						|
      wide_data[15] <= 'h00;
 | 
						|
      wide_data[16] <= 'h01;
 | 
						|
      wide_data[17] <= 00;
 | 
						|
      wide_data[18] <= 00;
 | 
						|
      wide_data[19] <= 00;
 | 
						|
      wide_data[20] <= 00;
 | 
						|
      wide_data[21] <= 00;
 | 
						|
      wide_data[22] <= 00;
 | 
						|
      wide_data[23] <= 00;
 | 
						|
      wide_data[24] <= 00;
 | 
						|
      wide_data[25] <= 00;
 | 
						|
      wide_data[26] <= 00;
 | 
						|
      wide_data[27] <= 00;
 | 
						|
      wide_data[28] <= 00;
 | 
						|
      wide_data[29] <= 00;
 | 
						|
      wide_data[30] <= 00;
 | 
						|
      wide_data[31] <= 00;
 | 
						|
      wide_data[32] <= 00;
 | 
						|
      wide_data[33] <= 00;
 | 
						|
      wide_data[34] <= 00;
 | 
						|
      wide_data[35] <= 00;
 | 
						|
      wide_data[36] <= 00;
 | 
						|
      wide_data[37] <= 00;
 | 
						|
      wide_data[38] <= 00;
 | 
						|
      wide_data[39] <= 00;
 | 
						|
      wide_data[40] <= 00;
 | 
						|
      wide_data[41] <= 00;
 | 
						|
      wide_data[42] <= 00;
 | 
						|
      wide_data[43] <= 00;
 | 
						|
      wide_data[44] <= 00;
 | 
						|
      wide_data[45] <= 00;
 | 
						|
      wide_data[46] <= 00;
 | 
						|
      wide_data[47] <= 00;
 | 
						|
      wide_data[48] <= 00;
 | 
						|
      wide_data[49] <= 00;
 | 
						|
      wide_data[50] <= 00;
 | 
						|
      wide_data[51] <= 00;
 | 
						|
      wide_data[52] <= 00;
 | 
						|
      wide_data[53] <= 00;
 | 
						|
      wide_data[54] <= 00;
 | 
						|
      wide_data[55] <= 00;
 | 
						|
      wide_data[56] <= 00;
 | 
						|
      wide_data[57] <= 00;
 | 
						|
      wide_data[58] <= 00;
 | 
						|
      wide_data[59] <= 00;
 | 
						|
      wide_data[60] <= 00;
 | 
						|
      wide_data[61] <= 00;
 | 
						|
      wide_data[62] <= 00;
 | 
						|
      wide_data[63] <= 00;
 | 
						|
/* -----\/----- EXCLUDED -----\/-----
 | 
						|
      wide_data[0] <= 00;
 | 
						|
      wide_data[1] <= 20;
 | 
						|
      wide_data[2] <= 80;
 | 
						|
      wide_data[3] <= 01;
 | 
						|
      wide_data[4] <= 80;
 | 
						|
      wide_data[5] <= 01;
 | 
						|
      wide_data[6] <= 80;
 | 
						|
      wide_data[7] <= 01;
 | 
						|
      wide_data[8] <= 80;
 | 
						|
      wide_data[9] <= 01;
 | 
						|
      wide_data[10] <= 80;
 | 
						|
      wide_data[11] <= 01;
 | 
						|
      wide_data[12] <= 80;
 | 
						|
      wide_data[13] <= 03;
 | 
						|
      wide_data[14] <= 00;
 | 
						|
      wide_data[15] <= 00;
 | 
						|
      wide_data[16] <= 01;
 | 
						|
      wide_data[17] <= 00;
 | 
						|
      wide_data[18] <= 00;
 | 
						|
      wide_data[19] <= 00;
 | 
						|
      wide_data[20] <= 00;
 | 
						|
      wide_data[21] <= 00;
 | 
						|
      wide_data[22] <= 00;
 | 
						|
      wide_data[23] <= 00;
 | 
						|
      wide_data[24] <= 00;
 | 
						|
      wide_data[25] <= 00;
 | 
						|
      wide_data[26] <= 00;
 | 
						|
      wide_data[27] <= 00;
 | 
						|
      wide_data[28] <= 00;
 | 
						|
      wide_data[29] <= 00;
 | 
						|
      wide_data[30] <= 00;
 | 
						|
      wide_data[31] <= 00;
 | 
						|
      wide_data[32] <= 00;
 | 
						|
      wide_data[33] <= 00;
 | 
						|
      wide_data[34] <= 00;
 | 
						|
      wide_data[35] <= 00;
 | 
						|
      wide_data[36] <= 00;
 | 
						|
      wide_data[37] <= 00;
 | 
						|
      wide_data[38] <= 00;
 | 
						|
      wide_data[39] <= 00;
 | 
						|
      wide_data[40] <= 00;
 | 
						|
      wide_data[41] <= 00;
 | 
						|
      wide_data[42] <= 00;
 | 
						|
      wide_data[43] <= 00;
 | 
						|
      wide_data[44] <= 00;
 | 
						|
      wide_data[45] <= 00;
 | 
						|
      wide_data[46] <= 00;
 | 
						|
      wide_data[47] <= 00;
 | 
						|
      wide_data[48] <= 00;
 | 
						|
      wide_data[49] <= 00;
 | 
						|
      wide_data[50] <= 00;
 | 
						|
      wide_data[51] <= 00;
 | 
						|
      wide_data[52] <= 00;
 | 
						|
      wide_data[53] <= 00;
 | 
						|
      wide_data[54] <= 00;
 | 
						|
      wide_data[55] <= 00;
 | 
						|
      wide_data[56] <= 00;
 | 
						|
      wide_data[57] <= 00;
 | 
						|
      wide_data[58] <= 00;
 | 
						|
      wide_data[59] <= 00;
 | 
						|
      wide_data[60] <= 00;
 | 
						|
      wide_data[61] <= 00;
 | 
						|
      wide_data[62] <= 00;
 | 
						|
      wide_data[63] <= 00;
 | 
						|
 -----/\----- EXCLUDED -----/\----- */
 | 
						|
   end
 | 
						|
   
 | 
						|
   
 | 
						|
 | 
						|
   integer   k;
 | 
						|
   
 | 
						|
   reg qCmd; 
 | 
						|
   reg [2:0] crcCnt;
 | 
						|
 | 
						|
   reg 	     add_wrong_cmd_crc;
 | 
						|
   reg 	     add_wrong_cmd_indx;
 | 
						|
   reg 	     add_wrong_data_crc;
 | 
						|
 | 
						|
   initial begin 
 | 
						|
      add_wrong_data_crc<=0;
 | 
						|
      add_wrong_cmd_indx<=0;
 | 
						|
      add_wrong_cmd_crc<=0;
 | 
						|
      stop<=1;
 | 
						|
      cardIdentificationState<=1;
 | 
						|
      state<=IDLE;
 | 
						|
      dataState<=DATA_IDLE;
 | 
						|
      Busy<=0;
 | 
						|
      oeCmd<=0;
 | 
						|
      crcCnt<=0;
 | 
						|
      CardTransferActive<=0;
 | 
						|
      qCmd<=1;
 | 
						|
      oeDat<=0;
 | 
						|
      cmdOut<=0;
 | 
						|
      cmdWrite<=0;  
 | 
						|
      InbuffStatus<=0;
 | 
						|
      datOut<=0;
 | 
						|
      inCmd<=0;
 | 
						|
      BusWidth<=1;
 | 
						|
      responseType=0;
 | 
						|
      mult_read=0;
 | 
						|
      mult_write=0;
 | 
						|
      crcIn<=0;
 | 
						|
      response_S<=0;
 | 
						|
      crcEn<=0;
 | 
						|
      crcRst<=0;
 | 
						|
      cmdRead<=0;
 | 
						|
      ValidCmd<=0;
 | 
						|
      inValidCmd=0;
 | 
						|
      appendCrc<=0;
 | 
						|
      RCA<= `RCASTART;
 | 
						|
      OCR<= `OCRSTART;
 | 
						|
      CardStatus <= `STATUSSTART;
 | 
						|
      CID<=`CIDSTART;
 | 
						|
      CSD<=`CSDSTART;
 | 
						|
      response_CMD<=0;
 | 
						|
      outDelayCnt<=0;
 | 
						|
      crcDat_rst<=1;
 | 
						|
      crcDat_en<=0;
 | 
						|
      crcDat_in<=0; 
 | 
						|
      transf_cnt<=0;
 | 
						|
      ByteAddr<=0;
 | 
						|
      block_cnt <=0;     
 | 
						|
      wptr<=0;
 | 
						|
      transf_cnt<=0;
 | 
						|
      crcDat_rst<=1;
 | 
						|
      crcDat_en<=0;
 | 
						|
      crcDat_in<=0; 
 | 
						|
      flash_write_cnt<=0;
 | 
						|
      startUppCnt<=0;
 | 
						|
      flash_blockwrite_cnt<=0;
 | 
						|
   end
 | 
						|
 | 
						|
   //CARD logic
 | 
						|
 | 
						|
   always @ (state or cmd or cmdRead or ValidCmd or inValidCmd or cmdWrite or outDelayCnt)
 | 
						|
     begin : FSM_COMBO
 | 
						|
	next_state  = 0;   
 | 
						|
	case(state)  
 | 
						|
	  IDLE: begin
 | 
						|
	     if (!cmd) 
 | 
						|
	       next_state = READ_CMD;
 | 
						|
	     else
 | 
						|
	       next_state = IDLE; 
 | 
						|
	  end  
 | 
						|
	  READ_CMD: begin
 | 
						|
	     if (cmdRead>= 47) 
 | 
						|
	       next_state = ANALYZE_CMD;
 | 
						|
	     else
 | 
						|
	       next_state =  READ_CMD; 
 | 
						|
	  end
 | 
						|
	  ANALYZE_CMD: begin
 | 
						|
	     if ((ValidCmd  )   & (outDelayCnt >= `outDelay )) // outDelayCnt >= 4 (NCR)
 | 
						|
	       next_state = SEND_CMD;
 | 
						|
	     else if (inValidCmd)
 | 
						|
	       next_state =  IDLE; 
 | 
						|
	     else
 | 
						|
	       next_state =  ANALYZE_CMD; 
 | 
						|
	  end 
 | 
						|
	  SEND_CMD: begin
 | 
						|
	     if (cmdWrite>= response_S) 
 | 
						|
	       next_state = IDLE;
 | 
						|
	     else
 | 
						|
	       next_state =  SEND_CMD; 
 | 
						|
	     
 | 
						|
	  end
 | 
						|
	  
 | 
						|
	  
 | 
						|
	endcase
 | 
						|
     end
 | 
						|
 | 
						|
   always @ (dataState or CardStatus or crc_c or flash_write_cnt or dat[0] )
 | 
						|
     begin : FSM_COMBODAT
 | 
						|
	next_datastate  = 0;   
 | 
						|
	case(dataState)  
 | 
						|
	  DATA_IDLE: begin
 | 
						|
	     if ((CardStatus[12:9]==`RCV) |  (mult_write == 1'b1) )  
 | 
						|
	       next_datastate = READ_WAITS;
 | 
						|
	     else if ((CardStatus[12:9]==`DATAS )|  (mult_read == 1'b1) ) 
 | 
						|
	       next_datastate = WRITE_DATA;
 | 
						|
	     else
 | 
						|
	       next_datastate = DATA_IDLE; 
 | 
						|
	  end  
 | 
						|
	  
 | 
						|
	  READ_WAITS: begin
 | 
						|
	     if ( dat[0] == 1'b0 ) 
 | 
						|
	       next_datastate =  READ_DATA;
 | 
						|
	     else
 | 
						|
	       next_datastate =  READ_WAITS; 
 | 
						|
	  end
 | 
						|
	  
 | 
						|
	  READ_DATA : begin  
 | 
						|
	     if (crc_c==0  ) 
 | 
						|
	       next_datastate =  WRITE_FLASH;
 | 
						|
	     else begin
 | 
						|
		if (stop == 1'b0)
 | 
						|
		  next_datastate =  READ_DATA;
 | 
						|
		else
 | 
						|
		  next_datastate =  DATA_IDLE;
 | 
						|
	     end
 | 
						|
 | 
						|
	  end
 | 
						|
	  WRITE_FLASH : begin
 | 
						|
	     if (flash_write_cnt>265 ) 	
 | 
						|
	       next_datastate =  DATA_IDLE;
 | 
						|
	     else 
 | 
						|
	       next_datastate =  WRITE_FLASH;
 | 
						|
	     
 | 
						|
	  end  
 | 
						|
 | 
						|
	  WRITE_DATA : begin   
 | 
						|
	     if (transf_cnt >= BLOCK_WIDTH) // transf_cnt >= 1044
 | 
						|
	       next_datastate= DATA_IDLE;  
 | 
						|
	     else 
 | 
						|
	       begin
 | 
						|
		  if (stop == 1'b0)
 | 
						|
		    next_datastate=WRITE_DATA;  
 | 
						|
		  else
 | 
						|
		    next_datastate =  DATA_IDLE;
 | 
						|
               end
 | 
						|
	  end
 | 
						|
	  
 | 
						|
	endcase
 | 
						|
     end
 | 
						|
 | 
						|
   always @ (posedge sdClk  )
 | 
						|
     begin 
 | 
						|
	
 | 
						|
	q_start_bit <= dat[0];
 | 
						|
     end
 | 
						|
 | 
						|
   always @ (posedge sdClk  )
 | 
						|
     begin : FSM_SEQ
 | 
						|
	state <= next_state; 
 | 
						|
     end
 | 
						|
 | 
						|
   always @ (posedge sdClk  )
 | 
						|
     begin : FSM_SEQDAT
 | 
						|
	dataState <= next_datastate; 
 | 
						|
     end
 | 
						|
 | 
						|
   always @ (posedge sdClk) begin
 | 
						|
      if (CardTransferActive) begin
 | 
						|
	 if (InbuffStatus==0) //empty
 | 
						|
	   CardStatus[8]<=1;
 | 
						|
	 else
 | 
						|
	   CardStatus[8]<=0;
 | 
						|
      end
 | 
						|
      else
 | 
						|
	CardStatus[8]<=1;
 | 
						|
      startUppCnt<=startUppCnt+1;
 | 
						|
      OCR[31]<=Busy; // THERE IS NO TILDA "OCR[31]<=~BUSY", BUSY is OCR[31]
 | 
						|
      if (startUppCnt == `TIME_BUSY) // startUppCnt == 63 (counts until ACMD41 valid)
 | 
						|
	Busy <=1;
 | 
						|
   end // always @ (posedge sdClk)
 | 
						|
   
 | 
						|
 | 
						|
   always @ (posedge sdClk) begin
 | 
						|
      qCmd<=cmd;
 | 
						|
   end
 | 
						|
 | 
						|
   //read data and cmd on rising edge
 | 
						|
   always @ (posedge sdClk) begin
 | 
						|
      case(state)
 | 
						|
	IDLE: begin
 | 
						|
	   mult_write <= 0; 
 | 
						|
	   mult_read <=0; 
 | 
						|
	   crcIn<=0;
 | 
						|
	   crcEn<=0;
 | 
						|
	   crcRst<=1;
 | 
						|
	   oeCmd<=0;
 | 
						|
	   stop<=0;
 | 
						|
	   cmdRead<=0;
 | 
						|
	   appendCrc<=0;
 | 
						|
	   ValidCmd<=0;
 | 
						|
	   inValidCmd=0;
 | 
						|
	   cmdWrite<=0;
 | 
						|
	   crcCnt<=0;
 | 
						|
	   response_CMD<=0;
 | 
						|
	   response_S<=0;
 | 
						|
	   outDelayCnt<=0;
 | 
						|
	   responseType=0;      
 | 
						|
	end // case: IDLE
 | 
						|
	
 | 
						|
	READ_CMD: begin //read cmd
 | 
						|
	   crcEn<=1;
 | 
						|
	   crcRst<=0;
 | 
						|
	   crcIn <= #`tIH qCmd; // tIH 0
 | 
						|
	   inCmd[47-cmdRead]  <= #`tIH qCmd;    // tIH 0
 | 
						|
	   cmdRead <= #1 cmdRead+1;
 | 
						|
	   if (cmdRead >= 40) 
 | 
						|
             crcEn<=0;
 | 
						|
           
 | 
						|
	   if (cmdRead == 46) begin
 | 
						|
              oeCmd<=1;
 | 
						|
	      cmdOut<=1;
 | 
						|
	   end
 | 
						|
	end // case: READ_CMD
 | 
						|
	
 | 
						|
        
 | 
						|
	ANALYZE_CMD: begin//check for valid cmd
 | 
						|
	   //Wrong CRC go idle
 | 
						|
	   if (inCmd[46] == 0) //start
 | 
						|
	     inValidCmd=1;
 | 
						|
	   else if (inCmd[7:1] != crcOut) begin
 | 
						|
	      inValidCmd=1;
 | 
						|
	      $fdisplay(sdModel_file_desc, "**sd_Model Command Packet - CRC Error") ;
 | 
						|
	      $display(sdModel_file_desc, "**sd_Model Command Packet - CRC Error") ;
 | 
						|
	   end  
 | 
						|
	   else if  (inCmd[0] != 1)  begin//stop 
 | 
						|
	      inValidCmd=1;
 | 
						|
	      $fdisplay(sdModel_file_desc, "**sd_Model Command Packet - No Stop Bit Error") ;
 | 
						|
	      $display(sdModel_file_desc, "**sd_Model Command Packet - No Stop Bit Error") ;
 | 
						|
	   end  
 | 
						|
	   else begin
 | 
						|
	      if(outDelayCnt ==0 )
 | 
						|
		CardStatus[3]<=0; // AKE_SEQ_ERROR = no error in sequence of authentication process, until I say otherwise
 | 
						|
	      case(inCmd[45:40])
 | 
						|
		0 : response_S <= 0; // GO_IDLE_STATE
 | 
						|
		2 : response_S <= 136; //ALL_SEND_CARD_ID (CID)
 | 
						|
		3 : response_S <= 48; //SEND_RELATIVE_CARD_ADDRESS (RCA)
 | 
						|
		7 : response_S <= 48; // SELECT_CARD
 | 
						|
		8 : response_S <= 48; // SEND_INTERFACE_CONDITION (IC)
 | 
						|
		9 : response_S <= 136; // SEND_CARD_SPECIFIC_DATA (CSD)
 | 
						|
		14 : response_S <= 0; // reserved (why is this even here?)
 | 
						|
		16 : response_S <= 48; // SET_BLOCK_LENGTH (Does nothing for SDHC/SDXC)
 | 
						|
		17 : response_S <= 48; // READ_SINGLE_BLOCK of data from card
 | 
						|
		18 : response_S <= 48; // READ_MULTIPLE_BLOCKS of data from card
 | 
						|
		24 : response_S <= 48; // WRITE_BLOCK of data to card
 | 
						|
		25 : response_S <= 48; // WRITE_MULTIPLE_BLOCKS of data to card
 | 
						|
		33 : response_S <= 48; // ERASE_WR_BLK_END
 | 
						|
		55 : response_S <= 48; // APP_CMD
 | 
						|
		41 : response_S <= 48; // CMD41 - SD_SEND_OCR
 | 
						|
	      endcase // case (inCmd[45:40])
 | 
						|
	      
 | 
						|
              case(inCmd[45:40])
 | 
						|
		0 : begin // GO_IDLE_STATE
 | 
						|
		   response_CMD <= 0;
 | 
						|
		   cardIdentificationState<=1;
 | 
						|
		   ResetCard;
 | 
						|
		end    
 | 
						|
		2 : begin //ALL_SEND_CARD_ID (CID)
 | 
						|
		   if (lastCMD != 41 & outDelayCnt==0) begin
 | 
						|
		      $fdisplay(sdModel_file_desc, "**Error in sequence, ACMD 41 should precede 2 in Start-up state") ;
 | 
						|
		      //$display(sdModel_file_desc, "**Error in sequence, ACMD 41 should precede 2 in Start-up state") ;
 | 
						|
		      CardStatus[3]<=1; // AKE_SEQ_ERROR = ERROR in sequence of authentication process
 | 
						|
		   end  
 | 
						|
		   response_CMD[127:8] <= CID;
 | 
						|
		   appendCrc<=0; 
 | 
						|
		   CardStatus[12:9] <=2;
 | 
						|
		end
 | 
						|
		3 :  begin //SEND_RELATIVE_CARD_ADDRESS (RCA)
 | 
						|
		   if (lastCMD != 2 & outDelayCnt==0 ) begin
 | 
						|
		      $fdisplay(sdModel_file_desc, "**Error in sequence, CMD 2 should precede 3 in Start-up state") ;
 | 
						|
		      //$display(sdModel_file_desc, "**Error in sequence, CMD 2 should precede 3 in Start-up state") ;
 | 
						|
		      CardStatus[3]<=1; // AKE_SEQ_ERROR = ERROR in sequence of authentication process
 | 
						|
		   end  
 | 
						|
		   response_CMD[127:112] <= RCA[15:0] ;
 | 
						|
		   response_CMD[111:96] <= CardStatus[15:0] ;
 | 
						|
		   appendCrc<=1;
 | 
						|
		   CardStatus[12:9] <=3;
 | 
						|
		   cardIdentificationState<=0;
 | 
						|
		end
 | 
						|
		6 : begin         
 | 
						|
		   if (lastCMD == 55 & outDelayCnt==0) begin //ACMD6 - SET_BUS_WIDTH
 | 
						|
		      if (inCmd[9:8] == 2'b10) begin
 | 
						|
			 BusWidth <=4;      
 | 
						|
			 $display(sdModel_file_desc, "**BUS WIDTH 4 ") ;
 | 
						|
		      end
 | 
						|
		      else
 | 
						|
			BusWidth <=1;               
 | 
						|
		      
 | 
						|
		      response_S<=48;
 | 
						|
		      response_CMD[127:96] <= CardStatus; 
 | 
						|
		   end   
 | 
						|
		   else if (outDelayCnt==0) begin //CMD6 - SWITCH_CARD_FUNCTION (Clock speed) 
 | 
						|
		      if (CardStatus[12:9] == `TRAN) begin //If card is in transfer state                               
 | 
						|
			 CardStatus[12:9] <=`DATAS;//Put card in data state
 | 
						|
			 response_CMD[127:96] <= CardStatus ;
 | 
						|
			 response_S<=48;
 | 
						|
			 BLOCK_WIDTH <= 11'd148;
 | 
						|
			 $fdisplay(sdModel_file_desc, "**Error Invalid CMD, %h",inCmd[45:40]);
 | 
						|
			 $display(sdModel_file_desc, "**Error Invalid CMD, %h",inCmd[45:40]);         
 | 
						|
		      end
 | 
						|
		      else begin
 | 
						|
			 response_S <= 0;
 | 
						|
			 response_CMD[127:96] <= 0;
 | 
						|
			 $fdisplay(sdModel_file_desc, "**Error Invalid CMD, %h, card not in transfer state",inCmd[45:40]);
 | 
						|
			 $display(sdModel_file_desc,  "**Error Invalid CMD, %h, card not in transfer state",inCmd[45:40]);
 | 
						|
		      end // else: !if(CardStatus[12:9] == `TRAN)
 | 
						|
		   end // if (outDelayCnt==0)
 | 
						|
		end // case: 6
 | 
						|
		
 | 
						|
		7: begin // SELECT_CARD
 | 
						|
		   if (outDelayCnt==0) begin 
 | 
						|
		      if (inCmd[39:24]== RCA[15:0]) begin
 | 
						|
			 CardTransferActive <= 1;
 | 
						|
			 response_CMD[127:96] <= CardStatus ; 
 | 
						|
			 CardStatus[12:9] <=`TRAN;                            
 | 
						|
		      end
 | 
						|
		      else begin
 | 
						|
			 CardTransferActive <= 0;
 | 
						|
			 response_CMD[127:96] <= CardStatus ; 
 | 
						|
			 CardStatus[12:9] <=3;  
 | 
						|
		      end          
 | 
						|
		   end        
 | 
						|
		end // case: 7
 | 
						|
		
 | 
						|
      
 | 
						|
		8 : begin // SEND_INTERFACE_CONDITION (IC)
 | 
						|
		   response_CMD[127:96] <= {20'h00000 , inCmd[19:8]}; //not supported by V1.0 card
 | 
						|
		   response_S<=48;
 | 
						|
		   
 | 
						|
		   $fdisplay(sdModel_file_desc, "**Warning Unofficially Supported CMD, %h",inCmd[45:40]);
 | 
						|
		   $display(sdModel_file_desc, "**Warning Unofficially Supported CMD, %h",inCmd[45:40]);
 | 
						|
		end
 | 
						|
		
 | 
						|
		9 : begin // SEND_CARD_SPECIFIC_DATA (CSD)
 | 
						|
		   if (lastCMD != 41 & outDelayCnt==0) begin
 | 
						|
		      $fdisplay(sdModel_file_desc, "**Error in sequence, ACMD 41 should precede 9 in Start-up state") ;
 | 
						|
		      //$display(sdModel_file_desc, "**Error in sequence, ACMD 41 should precede 9 in Start-up state") ;
 | 
						|
		      CardStatus[3]<=1; // AKE_SEQ_ERROR = ERROR in sequence of authentication process
 | 
						|
		   end  
 | 
						|
		   response_CMD[127:8] <= CSD;
 | 
						|
		   appendCrc<=0; 
 | 
						|
		   CardStatus[12:9] <=2;
 | 
						|
		end
 | 
						|
		
 | 
						|
		12: begin // STOP_TRANSMISSION
 | 
						|
		   response_CMD[127:96] <= CardStatus ;
 | 
						|
		   stop<=1;
 | 
						|
		   mult_write <= 0; 
 | 
						|
		   mult_read <=0; 
 | 
						|
		   CardStatus[12:9] <= `TRAN;
 | 
						|
		end 
 | 
						|
 | 
						|
		16 : begin // SET_BLOCK_LENGTH (Does nothing for SDHC/SDXC)
 | 
						|
		   response_CMD[127:96] <= CardStatus ;
 | 
						|
		end 
 | 
						|
 | 
						|
		17 :  begin // READ_SINGLE_BLOCK of data from card
 | 
						|
		   if (outDelayCnt==0) begin 
 | 
						|
		      if (CardStatus[12:9] == `TRAN) begin //If card is in transfer state                               
 | 
						|
			 CardStatus[12:9] <=`DATAS;//Put card in data state
 | 
						|
			 response_CMD[127:96] <= CardStatus ;
 | 
						|
			 BLOCK_WIDTH <= 11'd1044;
 | 
						|
			 
 | 
						|
			 ByteAddr = inCmd[39:8] << 9;
 | 
						|
			 if (ByteAddr%512 !=0)
 | 
						|
			   $display("**Block Misalign Error");         
 | 
						|
		      end
 | 
						|
		      else begin
 | 
						|
			 response_S <= 0;
 | 
						|
			 response_CMD[127:96] <= 0; 
 | 
						|
		      end
 | 
						|
		   end		   
 | 
						|
		end 
 | 
						|
 | 
						|
		18 :  begin // READ_MULTIPLE_BLOCKS of data from card
 | 
						|
		   if (outDelayCnt==0) begin 
 | 
						|
		      if (CardStatus[12:9] == `TRAN) begin //If card is in transfer state                               
 | 
						|
			 CardStatus[12:9] <=`DATAS;//Put card in data state
 | 
						|
			 response_CMD[127:96] <= CardStatus ;
 | 
						|
			 mult_read <= 1;
 | 
						|
			 ByteAddr = inCmd[39:8] << 9;
 | 
						|
			 if (ByteAddr%512 !=0)
 | 
						|
			   $display("**Block Misalign Error");         
 | 
						|
		      end
 | 
						|
		      else begin
 | 
						|
			 response_S <= 0;
 | 
						|
			 response_CMD[127:96] <= 0; 			 
 | 
						|
		      end
 | 
						|
		   end		   
 | 
						|
		end 
 | 
						|
		
 | 
						|
		24 : begin // WRITE_BLOCK of data to card
 | 
						|
		   if (outDelayCnt==0) begin 
 | 
						|
		      if (CardStatus[12:9] == `TRAN) begin //If card is in transfer state
 | 
						|
			 if (CardStatus[8]) begin //If Free write buffer           
 | 
						|
			    CardStatus[12:9] <=`RCV;//Put card in Rcv state
 | 
						|
			    response_CMD[127:96] <= CardStatus ;
 | 
						|
			    ByteAddr = inCmd[39:8] << 9;
 | 
						|
			    if (ByteAddr%512 !=0)
 | 
						|
			      $display("**Block Misalign Error");
 | 
						|
			 end
 | 
						|
			 else begin
 | 
						|
			    response_CMD[127:96] <= CardStatus;
 | 
						|
			    $fdisplay(sdModel_file_desc, "**Error Try to blockwrite when No Free Writebuffer") ;
 | 
						|
			    $display("**Error Try to blockwrite when No Free Writebuffer") ;
 | 
						|
			 end
 | 
						|
		      end
 | 
						|
		      else begin
 | 
						|
			 response_S <= 0;
 | 
						|
			 response_CMD[127:96] <= 0; 
 | 
						|
		      end
 | 
						|
		   end
 | 
						|
		end // case: 24
 | 
						|
		
 | 
						|
		25 : begin // WRITE_MULTIPLE_BLOCKS of data to card
 | 
						|
		   if (outDelayCnt==0) begin 
 | 
						|
		      if (CardStatus[12:9] == `TRAN) begin //If card is in transfer state
 | 
						|
			 if (CardStatus[8]) begin //If Free write buffer           
 | 
						|
			    CardStatus[12:9] <=`RCV;//Put card in Rcv state
 | 
						|
			    response_CMD[127:96] <= CardStatus ;
 | 
						|
			    ByteAddr = inCmd[39:8] << 9;
 | 
						|
			    mult_write <= 1;
 | 
						|
			    if (ByteAddr%512 !=0)
 | 
						|
			      $display("**Block Misalign Error");
 | 
						|
			 end
 | 
						|
			 else begin
 | 
						|
			    response_CMD[127:96] <= CardStatus;
 | 
						|
			    $fdisplay(sdModel_file_desc, "**Error Try to blockwrite when No Free Writebuffer") ;
 | 
						|
			    $display("**Error Try to blockwrite when No Free Writebuffer") ;
 | 
						|
			 end // else: !if(CardStatus[8])
 | 
						|
		      end // if (CardStatus[12:9] == `TRAN)
 | 
						|
		      else begin
 | 
						|
			 response_S <= 0;
 | 
						|
			 response_CMD[127:96] <= 0; 
 | 
						|
		      end // else: !if(CardStatus[12:9] == `TRAN)
 | 
						|
		   end // if (outDelayCnt==0)
 | 
						|
		end // case: 25
 | 
						|
 | 
						|
		33 : response_CMD[127:96] <= 48; // ERASE_WR_BLK_END
 | 
						|
		
 | 
						|
		55 : 
 | 
						|
		  begin // APP_CMD
 | 
						|
		     response_CMD[127:96] <= CardStatus ;         
 | 
						|
		     CardStatus[5] <=1;      //Next CMD is AP specific CMD
 | 
						|
		     appendCrc<=1;         
 | 
						|
		  end
 | 
						|
		
 | 
						|
		41 : // CMD41 - SD_SEND_OCR
 | 
						|
		  begin  
 | 
						|
		     if (cardIdentificationState) begin
 | 
						|
			if (lastCMD != 55 & outDelayCnt==0) begin // CMD41 - Reserved/Invalid
 | 
						|
			   $fdisplay(sdModel_file_desc, "**Error in sequence, CMD 55 should precede 41 in Start-up state") ;
 | 
						|
			   $display( "**Error in sequence, CMD 55 should precede 41 in Start-up state") ;
 | 
						|
			   CardStatus[3]<=1; // AKE_SEQ_ERROR = ERROR in sequence of authentication process
 | 
						|
			end
 | 
						|
			else begin // CMD41 - SD_SEND_OCR
 | 
						|
			   responseType=3; 
 | 
						|
			   response_CMD[127:96] <= OCR;   
 | 
						|
			   appendCrc<=0;
 | 
						|
			   CardStatus[5] <=0;  // not expecting next command to be ACMD
 | 
						|
			   if (Busy==1)
 | 
						|
			     CardStatus[12:9] <=1; // READY
 | 
						|
			end // else: !if(lastCMD != 55 & outDelayCnt==0)
 | 
						|
		     end // if (cardIdentificationState)
 | 
						|
		  end // case: 41
 | 
						|
	      endcase // case (inCmd[45:40])
 | 
						|
	      
 | 
						|
	      ValidCmd<=1;  
 | 
						|
	      crcIn<=0;
 | 
						|
	      
 | 
						|
	      outDelayCnt<=outDelayCnt+1;
 | 
						|
	      if (outDelayCnt==`outDelay)       // if (outDelayCnt == 4)
 | 
						|
		crcRst<=1;
 | 
						|
	      
 | 
						|
	      oeCmd<=1;
 | 
						|
	      cmdOut<=1;
 | 
						|
	      response_CMD[135:134] <=0; // Start bit = 0, tx bit = 0 (response from card)
 | 
						|
 | 
						|
	      // for those who aren't keeping track, we are still in 'else: !if(inCmd[0] != 1)'
 | 
						|
	      if (responseType != 3)
 | 
						|
		if (!add_wrong_cmd_indx)
 | 
						|
		  response_CMD[133:128] <=inCmd[45:40];
 | 
						|
		else
 | 
						|
		  response_CMD[133:128] <=0;
 | 
						|
              
 | 
						|
	      if (responseType == 3)
 | 
						|
		response_CMD[133:128] <=6'b111111;
 | 
						|
	      
 | 
						|
	      lastCMD <=inCmd[45:40];
 | 
						|
	   end // else: !if(inCmd[0] != 1)
 | 
						|
	end // case: ANALYZE_CMD
 | 
						|
      endcase // case (state)
 | 
						|
   end // always @ (posedge sdClk)
 | 
						|
 | 
						|
   always @ ( negedge sdClk) begin
 | 
						|
      case(state)
 | 
						|
 | 
						|
	SEND_CMD: begin
 | 
						|
	   crcRst<=0;
 | 
						|
	   crcEn<=1;
 | 
						|
	   cmdWrite<=cmdWrite+1;    
 | 
						|
	   if (response_S!=0)
 | 
						|
	     cmdOut<=0;   
 | 
						|
	   else
 | 
						|
	     cmdOut<=1;  
 | 
						|
	   
 | 
						|
	   if ((cmdWrite>0) &  (cmdWrite < response_S-8)) begin
 | 
						|
	      cmdOut<=response_CMD[135-cmdWrite];
 | 
						|
	      crcIn<=response_CMD[134-cmdWrite];
 | 
						|
	      if (cmdWrite >= response_S-9)
 | 
						|
		crcEn<=0;
 | 
						|
	   end
 | 
						|
	   else if (cmdWrite!=0) begin
 | 
						|
	      crcEn<=0;
 | 
						|
	      if (add_wrong_cmd_crc) begin
 | 
						|
		 cmdOut<=0;
 | 
						|
		 crcCnt<=crcCnt+1; 
 | 
						|
	      end
 | 
						|
	      else begin   
 | 
						|
		 cmdOut<=crcOut[6-crcCnt];
 | 
						|
		 crcCnt<=crcCnt+1; 
 | 
						|
		 if (responseType == 3)
 | 
						|
		   cmdOut<=1;
 | 
						|
	      end     
 | 
						|
	   end // if (cmdWrite!=0)
 | 
						|
	   if (cmdWrite == response_S-1)
 | 
						|
	     cmdOut<=1;
 | 
						|
	end // case: SEND_CMD
 | 
						|
      endcase // case (state)
 | 
						|
   end // always @ ( negedge sdClk)
 | 
						|
 | 
						|
   integer outdly_cnt;
 | 
						|
 | 
						|
   always @ (posedge sdClk) begin // Read DATA from host on positive clock edge
 | 
						|
      
 | 
						|
      case (dataState)
 | 
						|
	DATA_IDLE: begin
 | 
						|
 | 
						|
	   crcDat_rst<=1;
 | 
						|
	   crcDat_en<=0;
 | 
						|
	   crcDat_in<=0;       
 | 
						|
 | 
						|
	end
 | 
						|
	
 | 
						|
	READ_WAITS: begin
 | 
						|
	   oeDat<=0;
 | 
						|
	   crcDat_rst<=0;
 | 
						|
	   crcDat_en<=1;
 | 
						|
	   crcDat_in<=0; 
 | 
						|
	   crc_c<=15;//
 | 
						|
	   crc_ok<=1;      
 | 
						|
	end
 | 
						|
	
 | 
						|
	READ_DATA: begin
 | 
						|
	   
 | 
						|
	   InbuffStatus<=1;
 | 
						|
	   if (transf_cnt<`BIT_BLOCK_REC) begin
 | 
						|
	      if (wptr)
 | 
						|
		Inbuff[block_cnt][3:0] <= dat;
 | 
						|
	      else
 | 
						|
		Inbuff[block_cnt][7:4] <= dat;       
 | 
						|
	      
 | 
						|
	      if (!add_wrong_data_crc) 
 | 
						|
		crcDat_in<=dat;
 | 
						|
              else
 | 
						|
		crcDat_in<=4'b1010;
 | 
						|
              
 | 
						|
	      crc_ok<=1;
 | 
						|
	      transf_cnt<=transf_cnt+1; 
 | 
						|
	      if (wptr)
 | 
						|
		block_cnt<=block_cnt+1;     
 | 
						|
	      wptr<=~wptr;	      
 | 
						|
	   end // if (transf_cnt<`BIT_BLOCK_REC)
 | 
						|
	   
 | 
						|
	   else if  ( transf_cnt <= (`BIT_BLOCK_REC +`BIT_CRC_CYCLE-1)) begin
 | 
						|
	      transf_cnt<=transf_cnt+1; 
 | 
						|
	      crcDat_en<=0;  
 | 
						|
	      last_din <=dat; 
 | 
						|
	      
 | 
						|
	      if (transf_cnt> `BIT_BLOCK_REC) begin       
 | 
						|
		 crc_c<=crc_c-1;
 | 
						|
                 
 | 
						|
		 if (crcDat_out[0][crc_c] != last_din[0])
 | 
						|
		   crc_ok<=0;
 | 
						|
		 if  (crcDat_out[1][crc_c] != last_din[1])
 | 
						|
		   crc_ok<=0;
 | 
						|
		 if  (crcDat_out[2][crc_c] != last_din[2])
 | 
						|
		   crc_ok<=0;
 | 
						|
		 if  (crcDat_out[3][crc_c] != last_din[3])
 | 
						|
		   crc_ok<=0;         
 | 
						|
	      end // if (transf_cnt> `BIT_BLOCK_REC)
 | 
						|
	   end // if ( transf_cnt <= (`BIT_BLOCK_REC +`BIT_CRC_CYCLE-1))
 | 
						|
	end // case: READ_DATA
 | 
						|
 | 
						|
	WRITE_FLASH: begin
 | 
						|
	   oeDat<=1;
 | 
						|
	   block_cnt <=0;     
 | 
						|
	   wptr<=0;
 | 
						|
	   transf_cnt<=0;
 | 
						|
	   crcDat_rst<=1;
 | 
						|
	   crcDat_en<=0;
 | 
						|
	   crcDat_in<=0; 
 | 
						|
	end
 | 
						|
	
 | 
						|
      endcase // case (dataState)
 | 
						|
      
 | 
						|
   end // always @ (posedge sdClk)
 | 
						|
 | 
						|
   reg data_send_index;
 | 
						|
   integer write_out_index;
 | 
						|
   always @ (negedge sdClk) begin // Write DATA to Host on negative clock edge
 | 
						|
      
 | 
						|
      case (dataState)
 | 
						|
	DATA_IDLE: begin
 | 
						|
	   write_out_index<=0;
 | 
						|
	   transf_cnt<=0;
 | 
						|
	   data_send_index<=0; 
 | 
						|
	   outdly_cnt<=0;
 | 
						|
	   flash_write_cnt<=0;
 | 
						|
	end
 | 
						|
	
 | 
						|
	WRITE_DATA: begin
 | 
						|
	   oeDat<=1;
 | 
						|
	   outdly_cnt<=outdly_cnt+1;
 | 
						|
	   datOut <= 4'b1111; // listen... until I tell you otherwise, DAT bus is all high (thanks Ross)
 | 
						|
	   
 | 
						|
	   
 | 
						|
	   if ( outdly_cnt > `DLY_TO_OUTP) begin // if (outdly_cnt > 47) NAC cycles elapsed
 | 
						|
              transf_cnt <= transf_cnt+1; // start counting bits transferred
 | 
						|
              crcDat_en<=1; // Enable CRC16
 | 
						|
              crcDat_rst<=0; // Stop reset of CRC16
 | 
						|
	      oeDat<=1;   // Enable output
 | 
						|
	   end
 | 
						|
	   
 | 
						|
	   else begin // NAC cycles have not elapsed
 | 
						|
              crcDat_en<=0; // Disable CRC16 generation
 | 
						|
              crcDat_rst<=1; // Reset CRC16 generators
 | 
						|
              oeDat<=0;   // Do NOT enable output (I REALLY DO AGREE WITH THIS!)
 | 
						|
              crc_c<=16; // point to bit 16 of CRC16
 | 
						|
	   end // else: !if( outdly_cnt > `DLY_TO_OUTP)
 | 
						|
	   
 | 
						|
	   if (transf_cnt==1) begin  // first nibble
 | 
						|
              if (BLOCK_WIDTH == 11'd1044) begin
 | 
						|
		 last_din <= FLASHmem[ByteAddr+(write_out_index)][7:4]; // LOAD register with upper nibble
 | 
						|
		 crcDat_in<= FLASHmem[ByteAddr+(write_out_index)][7:4];  // LOAD CRC16 with upper nibble
 | 
						|
	      end
 | 
						|
	      else begin
 | 
						|
		 // code for wide width data
 | 
						|
		 last_din <= wide_data[write_out_index][7:4];
 | 
						|
		 crcDat_in <= wide_data[write_out_index][7:4];
 | 
						|
	      end
 | 
						|
	      datOut<=0; // Send nothing yet
 | 
						|
              data_send_index<=1; // Next nibble is lower nibble
 | 
						|
           end
 | 
						|
	   
 | 
						|
           else if ( (transf_cnt>=2) & (transf_cnt<=BLOCK_WIDTH -`CRC_OFF )) begin  // if (2 <= transf_cnt <= 1025)
 | 
						|
              data_send_index<=~data_send_index; //toggle
 | 
						|
              if (!data_send_index) begin //upper nibble
 | 
						|
		 if (BLOCK_WIDTH == 11'd1044) begin
 | 
						|
		    last_din <= FLASHmem[ByteAddr+(write_out_index)][7:4]; // LOAD register with upper nibble
 | 
						|
		    crcDat_in<= FLASHmem[ByteAddr+(write_out_index)][7:4];  // LOAD CRC16 with upper nibble
 | 
						|
		 end
 | 
						|
		 else begin
 | 
						|
		    // code for wide width data
 | 
						|
		    last_din <= wide_data[write_out_index][7:4];
 | 
						|
		    crcDat_in <= wide_data[write_out_index][7:4];
 | 
						|
		 end
 | 
						|
              end // if (!data_send_index)
 | 
						|
              else begin //lower nibble
 | 
						|
		 if (BLOCK_WIDTH == 11'd1044) begin
 | 
						|
		    last_din<=FLASHmem[ByteAddr+(write_out_index)][3:0];
 | 
						|
		 end
 | 
						|
		 else begin
 | 
						|
		    last_din <= wide_data[write_out_index][3:0];
 | 
						|
		 end		 
 | 
						|
		 if (!add_wrong_data_crc)
 | 
						|
		   if (BLOCK_WIDTH == 11'd1044) begin
 | 
						|
		      crcDat_in<= FLASHmem[ByteAddr+(write_out_index)][3:0];
 | 
						|
		   end
 | 
						|
		   else begin
 | 
						|
		      crcDat_in <= wide_data[write_out_index][3:0];
 | 
						|
		   end
 | 
						|
		 else // SNAFU
 | 
						|
		   crcDat_in<=4'b1010; 
 | 
						|
		 write_out_index<=write_out_index+1; // Having sent the lower nibble, increment the byte counter
 | 
						|
		 
 | 
						|
              end // else: !if(!data_send_index)
 | 
						|
              
 | 
						|
              datOut<= last_din; // output content of register
 | 
						|
              
 | 
						|
              
 | 
						|
              if ( transf_cnt >=BLOCK_WIDTH-`CRC_OFF ) begin // if (trans_cnt >= 1025)
 | 
						|
		 crcDat_en<=0;                              // Disable CRC16 Generators     
 | 
						|
              end   
 | 
						|
	   end // if ( (transf_cnt>=2) & (transf_cnt<=`BIT_BLOCK-`CRC_OFF ))
 | 
						|
	   
 | 
						|
	   else if (transf_cnt>BLOCK_WIDTH-`CRC_OFF & crc_c!=0) begin // if ((transf_cnt > 1025) and (crc_c /= 0))
 | 
						|
              datOut<= last_din; // if sent all data bitsbut not crc16 bits yet
 | 
						|
              crcDat_en<=0; // Disable CRC16 generators
 | 
						|
              crc_c<=crc_c-1; // point to next bit of CRC16 to begin transmission of CRC16
 | 
						|
              if (crc_c<= 16) begin // begin sending CRC16 (16 downto 1)
 | 
						|
		 datOut[0]<=crcDat_out[0][crc_c-1];
 | 
						|
		 datOut[1]<=crcDat_out[1][crc_c-1];
 | 
						|
		 datOut[2]<=crcDat_out[2][crc_c-1];
 | 
						|
		 datOut[3]<=crcDat_out[3][crc_c-1];       
 | 
						|
	      end 
 | 
						|
	      
 | 
						|
	   end // if (transf_cnt>`BIT_BLOCK-`CRC_OFF & crc_c!=0)
 | 
						|
	   else if (transf_cnt==BLOCK_WIDTH-2) begin     // if (transf_cnt = 1042) Last CRC16 bit is 1041
 | 
						|
              datOut<=4'b1111;          // send end bits
 | 
						|
	   end
 | 
						|
	   else if ((transf_cnt !=0) & (crc_c == 0 ))begin // if sent data bits and crc_c points past last bit of CRC
 | 
						|
              oeDat<=0; // disable output on DAT bus
 | 
						|
              CardStatus[12:9] <= `TRAN; // put card in transfer state
 | 
						|
           end
 | 
						|
	   
 | 
						|
	end // case: WRITE_DATA
 | 
						|
	
 | 
						|
	
 | 
						|
	WRITE_FLASH: begin
 | 
						|
	   flash_write_cnt<=flash_write_cnt+1;
 | 
						|
	   CardStatus[12:9] <= `PRG;
 | 
						|
	   datOut[0]<=0;
 | 
						|
	   datOut[1]<=1;
 | 
						|
	   datOut[2]<=1;
 | 
						|
	   datOut[3]<=1;
 | 
						|
	   if (flash_write_cnt == 0)
 | 
						|
	     datOut<=1;
 | 
						|
	   else if(flash_write_cnt == 1)
 | 
						|
	     datOut[0]<=1;
 | 
						|
	   else if(flash_write_cnt == 2)
 | 
						|
	     datOut[0]<=0;
 | 
						|
	   
 | 
						|
	   else if ((flash_write_cnt > 2) & (flash_write_cnt < 7)) begin
 | 
						|
	      if (crc_ok) 
 | 
						|
		datOut[0] <=okcrctoken[6-flash_write_cnt];
 | 
						|
	      else
 | 
						|
		datOut[0] <= invalidcrctoken[6-flash_write_cnt];
 | 
						|
	      
 | 
						|
	   end
 | 
						|
	   else if  ((flash_write_cnt >= 7) & (flash_write_cnt < 264)) begin
 | 
						|
	      datOut[0]<=0;
 | 
						|
	      
 | 
						|
	      flash_blockwrite_cnt<=flash_blockwrite_cnt+2;
 | 
						|
	      FLASHmem[ByteAddr+(flash_blockwrite_cnt)]=Inbuff[flash_blockwrite_cnt];
 | 
						|
	      FLASHmem[ByteAddr+(flash_blockwrite_cnt+1)]=Inbuff[flash_blockwrite_cnt+1];
 | 
						|
	   end
 | 
						|
	   
 | 
						|
	   else begin
 | 
						|
	      datOut<=1;      
 | 
						|
	      InbuffStatus<=0;
 | 
						|
	      CardStatus[12:9] <= `TRAN;
 | 
						|
	   end // else: !if((flash_write_cnt >= 7) & (flash_write_cnt < 264))   
 | 
						|
	end // case: WRITE_FLASH
 | 
						|
      endcase // case (dataState)
 | 
						|
   end // always @ (negedge sdClk)
 | 
						|
 | 
						|
   initial
 | 
						|
     begin
 | 
						|
	sdModel_file_desc = $fopen("sd_model.log");
 | 
						|
	if (sdModel_file_desc < 2)
 | 
						|
	  begin
 | 
						|
	     $display("*E Could not open/create testbench log file in /log/ directory!");
 | 
						|
	     $finish;
 | 
						|
	  end
 | 
						|
     end
 | 
						|
 | 
						|
   task ResetCard; //  MAC registers
 | 
						|
      begin
 | 
						|
	 add_wrong_data_crc<=0;
 | 
						|
	 add_wrong_cmd_indx<=0;
 | 
						|
	 add_wrong_cmd_crc<=0;
 | 
						|
	 cardIdentificationState<=1;
 | 
						|
	 state<=IDLE;
 | 
						|
	 dataState<=DATA_IDLE;
 | 
						|
	 Busy<=0;
 | 
						|
	 oeCmd<=0;
 | 
						|
	 crcCnt<=0;
 | 
						|
	 CardTransferActive<=0;
 | 
						|
	 qCmd<=1;
 | 
						|
	 oeDat<=0;
 | 
						|
	 cmdOut<=0;
 | 
						|
	 cmdWrite<=0;
 | 
						|
	 startUppCnt<=0;
 | 
						|
	 InbuffStatus<=0;
 | 
						|
	 datOut<=0;
 | 
						|
	 inCmd<=0;
 | 
						|
	 BusWidth<=1;
 | 
						|
	 responseType=0;
 | 
						|
	 crcIn<=0;
 | 
						|
	 response_S<=0;
 | 
						|
	 crcEn<=0;
 | 
						|
	 crcRst<=0;
 | 
						|
	 cmdRead<=0;
 | 
						|
	 ValidCmd<=0;
 | 
						|
	 inValidCmd=0;
 | 
						|
	 appendCrc<=0;
 | 
						|
	 RCA<= `RCASTART;
 | 
						|
	 OCR<= `OCRSTART;
 | 
						|
	 CardStatus <= `STATUSSTART;
 | 
						|
	 CID<=`CIDSTART;
 | 
						|
	 CSD<=`CSDSTART;
 | 
						|
	 response_CMD<=0;
 | 
						|
	 outDelayCnt<=0;
 | 
						|
	 crcDat_rst<=1;
 | 
						|
	 crcDat_en<=0;
 | 
						|
	 crcDat_in<=0; 
 | 
						|
	 transf_cnt<=0;
 | 
						|
	 ByteAddr<=0;
 | 
						|
	 block_cnt <=0;     
 | 
						|
	 wptr<=0;
 | 
						|
	 transf_cnt<=0;
 | 
						|
	 crcDat_rst<=1;
 | 
						|
	 crcDat_en<=0;
 | 
						|
	 crcDat_in<=0; 
 | 
						|
	 flash_write_cnt<=0;
 | 
						|
	 flash_blockwrite_cnt<=0;
 | 
						|
      end
 | 
						|
   endtask  
 | 
						|
   
 | 
						|
endmodule // sdModel
 |