// -----------------------------------------------------------------------
//
//   Copyright 2003-2021 H. Peter Anvin - All Rights Reserved
//
//   This program is free software; you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
//   Bostom MA 02111-1307, USA; either version 2 of the License, or
//   (at your option) any later version; incorporated herein by reference.
//
// -----------------------------------------------------------------------

//
// MMC/SD controller for MAX80
//
// This runs the SD card in SPI mode. In the future, consider improving
// performance by switching to quad SD mode.
//
// Note: this is also usable as generic SPI master in many cases.

module sdcard
 #(
   parameter [0:0]  with_crc7     = 1'b1,
   parameter [6:0]  crc7_poly     = 7'b000_1001,
   parameter [0:0]  with_crc16    = 1'b1,
   parameter [15:0] crc16_poly    = 16'b0001_0000_0010_0001,
   parameter [7:0]  with_irq_mask = 8'b0000_0000
   )
   (
    input	      rst_n,    // Global reset
    input	      clk,      // System clock (84 MHz)

    output	      sd_cs_n,  // SD card CS# (CD, DAT3)
    output	      sd_di,    // SD card DI (MOSI, CMD)
    output	      sd_sclk,  // SD card CLK (SCLK)
    input	      sd_do,    // SD card SO (MISO, DAT0)
    input	      sd_cd_n,  // Card detect
    input	      sd_irq_n, // External IRQ input (optional)

    input [31:0]      wdata,    // CPU data out (CPU->controller)
    output reg [31:0] rdata,    // CPU data in (controller->CPU)
    input	      valid,    // Memory valid
    input [3:0]       wstrb,    // Write strobes
    input [4:0]       addr,     // Address bits
    output	      wait_n,   // Hold mem_ready
    output	      irq	// CPU interrupt request
    );

   // ------------------------------------------------------------------------
   //  SD card interface
   //
   //  This drives the SD card in SPI mode.  We support two speeds:
   //  84 MHz/4 = 21 MHz for normal operation, and 84 MHz/256 = 328 kHz
   //  during initialization.
   //
   //  It exports the following I/O ports, address bits can be combined.
   //  The actual connection to the CPU bus shifts the addresses left
   //  by two so that dword accesses can be done.
   //
   //  Write:
   //  00000	- control register:
   //              [6:0] - speed divider (CPU_HZ/(2*(divider+1)))
   //                [7] - CS# active
   //             [15:8] - IRQ enable mask
   //               [22] - clear read CRC
   //               [23] - clear write CRC
   //
   //  x0xxx	- reserved
   //  x1e00     - load shift register but don't start transaction
   //  x1e01     - load shift register and start transaction, 8 bits
   //  x1e10     - load shift register and start transaction, 16 bits
   //  x1e11     - load shift register and start transaction, 32 bits
   //  11xxx     - clear write CRC registers
   //  e = endian; 0 = wire byte order; 1 = bigendian byte order
   //
   //  Note: the triggered bus transaction size is set by byte enables.
   //  The output latch should be written left-aligned (most significant
   //  bytes within a dword); the input latch right-aligned.
   //
   //  Read:
   //  00000	-  [15:0] - control register
   //                [16] - busy status
   //             [31:24] - IRQ status
   //  00100	-   [7:0] - read CRC7  + final 1 bit
   //             [31:16] - read CRC16
   //  00101	-   [7:0] - write CRC7 + final 1 bit
   //             [31:16] - write CRC16
   //  x0xxx    - reserved
   //  x1e00    - read shift register but don't start transaction
   //  x1e01    - read shift register and start transaction, 8 bits
   //  x1e10    - read shift register and start transaction, 16 bits
   //  x1e11    - read shift register and start transaction, 32 bits
   //  11xxx    - clear read CRC registers
   //
   //  Addresses of the form 000xx are non-blocking; others stall the CPU
   //  until the current transaction is complete.
   //
   //  Available interrupts are:
   //  0 - unit idle
   //  1 - card detect (sd_cd_n low)
   //  2 - external interrupt (sd_irq_n low)
   // ------------------------------------------------------------------------

   reg [31:0] sd_shr_out;
   reg [31:0] sd_shr_in;
   reg [31:0] sd_shr_in_q;
   reg [4:0]  sd_out_ctr;	// Output bit counter
   reg	      sd_active;	// Transfer in progress
   reg	      sd_active_neg;	// Transfer in progress, first pos clock seen
   reg	      sd_crcstb;	// Strobe for CRC generator
   reg	      sd_cs_reg;	// CS# active (positive logic, so inverted)
   wire       sd_data_out = sd_shr_out[31];
   reg	      sd_clk_out;	// Output clock signal

   // Output pins - tristate if card not present
   assign     sd_di   = ~sd_cd_n ? sd_data_out : 1'bz;
   assign     sd_sclk = ~sd_cd_n ? sd_clk_out : 1'bz;
   assign     sd_cs_n = ~sd_cd_n ? ~sd_cs_reg  : 1'bz;

   // If we try an action while a bus transaction is in progress,
   // wait.  The register sd_cmd_ok is used to prevent WAIT# from
   // being asserted when we already started a transaction on *this*
   // I/O operation.
   //
   // valid:      0 0 0 0 1 1 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0
   // sd_active:  0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1
   // sd_cmd:     0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
   // sd_cmd_ok:  0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0
   // cpu_wait_n: 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1
   //

   wire       valid_blocking = valid & (addr[4:2] != 3'b000);
   wire       sd_cmd = valid_blocking & ~sd_active;
   // CPU command we can act on
   reg	      sd_cmd_ok;	// Valid CPU command received

   always @(negedge rst_n or posedge clk)
     if (~rst_n)
       sd_cmd_ok <= 1'b0;
     else
       sd_cmd_ok <= valid_blocking & (~sd_active | sd_cmd_ok);

   //assign wait_n = ~(valid_blocking & sd_active) | sd_cmd_ok;
   assign wait_n = 1'b1;

   // Valid *nonblocking* command
   wire       sd_cmd_nonblock = valid & (addr[4:2] == 3'b000);

   // SD clock generator; this counter is used to generate the slow clock.
   reg [6:0]  sd_clk_div;
   reg [6:0]  sd_clk_ctr;
   reg	      sd_clk_stb;	// Clock strobe (clock flips next cycle)
   reg	      sd_clk_pol;	// Clock polarity
   wire       sd_clk_pos;	// SD clock positive strobe
   wire       sd_clk_neg;	// SD clock negative strobe

   always @(posedge clk)
     begin
	if (|sd_clk_ctr)
	  begin
	     sd_clk_stb <= 1'b0;
	     sd_clk_ctr <= sd_clk_ctr - 1'b1;
	  end
	else
	  begin
	     sd_clk_stb <= 1'b1;
	     sd_clk_pol <= ~sd_clk_pol; // Polarity of clock (one cycle early)
	     sd_clk_ctr <= sd_clk_div;
	  end
     end // always @ (posedge clk)

   // Generate strobes from the sd_clk_ctr; this is defined to be 1
   assign sd_clk_pos = sd_active     & sd_clk_stb &  sd_clk_pol;
   assign sd_clk_neg = sd_active_neg & sd_clk_stb & ~sd_clk_pol;

   always @(negedge rst_n or posedge clk)
     if (~rst_n)
       sd_clk_out <= 1'b0;
     else
       sd_clk_out <= (sd_clk_out | sd_clk_pos) & ~sd_clk_neg;

   // IRQ handling (extensible for future uses)
   reg [7:0] irq_status;
   always @(posedge clk)
     begin
	irq_status <= with_irq_mask &
		      {
		       5'b0, // Reserved for future uses
		       ~sd_irq_n,
		       ~sd_cd_n,
		       ~sd_active
		       };
     end
   reg [7:0] irq_en;

   assign     irq = |(irq_status & irq_en & with_irq_mask);

   //
   // Main shift register state machine
   //
   reg [1:0]  clear_crc;

   always @(negedge rst_n or posedge clk)
     if (~rst_n)
       begin
	  sd_shr_out    <= 32'hffff_ffff;
	  sd_cs_reg     <= 1'b0;
	  sd_clk_div    <= 7'h7f;
	  sd_active     <= 1'b0;
	  sd_active_neg <= 1'b0;
	  sd_out_ctr    <= 5'h0;
	  sd_crcstb     <= 1'b0;
	  sd_shr_in     <= 32'hffff_ffff;
	  sd_shr_in_q   <= 32'hffff_ffff;
	  clear_crc     <= 2'b11;
	  irq_en        <= 8'b0;
       end
     else
       begin
	  if (sd_clk_pos)
	    begin
	       sd_shr_in     <= {sd_shr_in[30:0], sd_do};
	       sd_out_ctr    <= sd_out_ctr + 1'b1;
	       sd_active_neg <= 1'b1;
	    end
	  if (sd_clk_neg)
	    begin
	       sd_shr_out    <= {sd_shr_out[30:0], 1'b1};
	       sd_active     <= |sd_out_ctr;
	       sd_active_neg <= |sd_out_ctr;
	       if (~|sd_out_ctr)
		 sd_shr_in_q <= sd_shr_in;
	    end

	  clear_crc <= 2'b00;	   // No clearing by default
	  sd_crcstb <= sd_clk_pos; // CRCs are computed one cycle after posedge

	  if (sd_cmd_nonblock)
	    casez(addr[1:0])
	      2'b00: begin
		 if (wstrb[0]) {sd_cs_reg, sd_clk_div} <= wdata[7:0];
		 if (wstrb[1]) irq_en <= wdata[15:8] & with_irq_mask;
		 if (wstrb[2]) clear_crc <= wdata[23:22];
	      end
	      default: begin
		 // Do nothing
	      end
	    endcase

	  if (sd_cmd)
	    begin
	       if (addr[4:3] == 2'b11)
		 clear_crc <= {|wstrb, ~|wstrb};

	       casez (addr)
		 5'b?10??: begin
		    // Load in host (littleendian) byte order
		    if (wstrb[3]) sd_shr_out[ 7: 0] <= wdata[31:24];
		    if (wstrb[2]) sd_shr_out[15: 8] <= wdata[23:16];
		    if (wstrb[1]) sd_shr_out[23:16] <= wdata[15: 8];
		    if (wstrb[0]) sd_shr_out[31:24] <= wdata[ 7: 0];
		 end
		 5'b?11??: begin
		    // Load in SPI (bigendian) byte order
		    if (wstrb[3]) sd_shr_out[31:24] <= wdata[31:24];
		    if (wstrb[2]) sd_shr_out[23:16] <= wdata[23:16];
		    if (wstrb[1]) sd_shr_out[15: 8] <= wdata[15: 8];
		    if (wstrb[0]) sd_shr_out[ 7: 0] <= wdata[ 7: 0];
		 end
		 default: begin
		    // do nothing
		 end
	       endcase

	       // Begin transaction
	       // Note: sd_out_ctr *increments*
	       if (addr[3])
		 case (addr[1:0])
		   2'b01: begin
		      /* Start 8-bit transaction */
		      sd_active  <= 1'b1;
		      sd_out_ctr <= 5'b11_000;
		   end
		   2'b10: begin
		      /* Start 16-bit transaction */
		      sd_active  <= 1'b1;
		      sd_out_ctr <= 5'b10_000;
		   end
		   2'b11: begin
		      /* Start 32-bit transaction */
		      sd_active  <= 1'b1;
		      sd_out_ctr <= 5'b00_000;
		   end
		   default: begin
		      // do nothing
		   end
		 endcase // case (addr[1:0])
	    end // if (sd_cmd)
       end // else: !if(~rst_n)

   //
   // CRC generators: we have two 7-bit and two 16-bit, one each for
   // input [0] and output [1].
   //
   // The CRC generators run one cycle behind the positive sd_clk strobe.

   wire [1:0] sd_crcbit = { sd_data_out, sd_shr_in[0] };

   reg  [6:0] sd_crc7 [0:1];	// CRC-7 shift register
   reg [15:0] sd_crc16[0:1];	// CRC-16 shift register

   always @(negedge rst_n or posedge clk)
     if (~rst_n)
       for (int i = 0; i < 2; i = i+1)
	 begin
	    sd_crc7[i]  <= 7'hxx;
	    sd_crc16[i] <= 16'hxxxx;
	 end
     else
       for (int i = 0; i < 2; i = i+1)
	 begin
	    if (clear_crc[i])
	      begin
		 sd_crc7[i]  <= 7'h00;
		 sd_crc16[i] <= 16'h0000;
	      end
	    else if (sd_crcstb)
	      begin
		 if (with_crc7)
		   sd_crc7[i]  <= { sd_crc7[i][5:0], 1'b0 }
				  ^ ({7{sd_crcbit[i] ^ sd_crc7[i][6]}}
				     & crc7_poly);
		 if (with_crc16)
		   sd_crc16[i] <= { sd_crc16[i][14:0], 1'b0 }
				  ^ ({16{sd_crcbit[i] ^ sd_crc16[i][15]}}
				     & crc16_poly);
	      end // else: !if(clear_crc[i])
	 end // for (int i = 0; i < 2; i = i+1)

   // Data out MUX
   always_comb
     begin
	casez (addr)
	  5'b0_0000: begin
	     rdata[31:16] = { irq_status, 7'b0, sd_active };
	     rdata[15: 0] = { irq_en, sd_cs_reg, sd_clk_div };
	  end
	  5'b0_0100: begin
	     rdata[31:16] = with_crc16 ? sd_crc16[0] : 16'b0;
	     rdata[15: 8] = 8'b0;
	     rdata[ 7: 0] = with_crc7  ? { sd_crc7[0], 1'b1 } : 8'b0;
	  end
	  5'b0_0101: begin
	     rdata[31:16] = with_crc16 ? sd_crc16[1] : 16'b0;
	     rdata[15: 8] = 8'b0;
	     rdata[ 7: 0] = with_crc7  ? { sd_crc7[1], 1'b1 } : 8'b0;
	  end
	  5'b?_10??: begin
	     rdata = { sd_shr_in_q[7:0], sd_shr_in_q[15:8],
		       sd_shr_in_q[23:16], sd_shr_in_q[31:24] };
	  end
	  5'b?_11??: begin
	     rdata = sd_shr_in_q;
	  end
	  default: begin
	     rdata = 32'hxxxx_xxxx;
	  end
	endcase
     end

endmodule // sdcard
