Subversion Repositories ngs

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. // part of NeoGS project
  2. //
  3. // (c) NedoPC 2007-2009
  4. //
  5. // SD-card dma controller
  6. //
  7. // includes dma address regs, dma control reg
  8. /*
  9.  
  10.  Read from sd-card modes:
  11.  
  12.   1. Full burst: first all 512 bytes are read into 512b buffer, then dma-bursted into main memory.
  13.      Not as fast in latency, but steals minimum of CPU cycles, though stops cpu for 1024+ clocks (if no other DMAs are active)
  14.  
  15.   2. As soon as possible: initiates DMA as soon as new byte is arrived into 512b buffer.
  16.      Makes bursts of 2-3 bytes, when applicable (more bytes arriven since beginning of dma_req up to acknowledge in dma_ack)
  17.  
  18.  Write to sd-card modes:
  19.  
  20.   1. Full burst: all 512 bytes are read in one burst, transmission starts as soon as first byte arrives to the buffer.
  21.      Uses minimum of CPU cycles (1024+) but in one chunk.
  22.  
  23.   2. DMA initiated as soon as spi is again ready to initiate new transfer (kind a throttling). Probably DMA pulls 2 or 4 bytes at once.
  24.  
  25. Structure:
  26.  
  27.  - FIFO based on mem512b and two pointers
  28.  
  29.  - SD controller - FSM which either reads or writes SD-card SPI iface
  30.  
  31.  - DMA controller - FSM which either reads or writes DMA iface
  32.  
  33.  - overall control - Controls operation of everything above, controls muxing of data to the
  34.    SD write port and FIFO write port, tracks operation end, maintains DMA_ADDRESS registers.
  35.  
  36. */
  37.  
  38.  
  39. module dma_sd(
  40.  
  41.         input  wire clk,
  42.         input  wire rst_n,
  43.  
  44.         // control to spi module of SD-card
  45.         //
  46.         output reg        sd_start,
  47.         input  wire       sd_rdy,
  48.         input  wire [7:0] sd_receiveddata,
  49.         output wire [7:0] sd_datatosend,
  50.         //
  51.         output reg        sd_override, // when 1, override sd_start and sd_datatosend to the sd spi module
  52.  
  53.  
  54.  
  55.         // signals for ports.v
  56.         //
  57.         input  wire [7:0] din,  // input and output from ports.v
  58.         output reg  [7:0] dout,
  59.         //
  60.         input  wire       module_select, // =1 - module selected for read-write operations from ports.v
  61.         input  wire       write_strobe,  // one-cycle positive write strobe - writes to the selected registers from din
  62.         //
  63.         input  wire [1:0] regsel, // 2'b00 - high address, 2'b01 - middle address, 2'b10 - low address, 2'b11 - control register
  64.  
  65.         // signals for DMA controller/DMA sequencer
  66.         //
  67.         output reg  [20:0] dma_addr,
  68.         output wire  [7:0] dma_wd,   // data written to DMA
  69.         input  wire  [7:0] dma_rd,   // data read from DMA
  70.         output reg         dma_rnw,
  71.         //
  72.         output wire        dma_req,
  73.         input  wire        dma_ack,
  74.         input  wire        dma_end
  75. );
  76.         localparam _HAD = 2'b00; // high address
  77.         localparam _MAD = 2'b01; // mid address
  78.         localparam _LAD = 2'b10; // low address
  79.         localparam _CST = 2'b11; // control and status
  80.  
  81.  
  82.         reg dma_snr;   // Send-NotReceive. Send to SDcard (==1) or Receive (==0) from it.
  83.         reg dma_burst; // whether burst transfers are on
  84.  
  85.  
  86.  
  87.  
  88.  
  89.         // control dout bus
  90.         always @*
  91.         case( regsel[1:0] )
  92.                 _HAD: dout = { 3'b000, dma_addr[20:16] };
  93.                 _MAD: dout =           dma_addr[15:8];
  94.                 _LAD: dout =           dma_addr[7:0];
  95.                 _CST: dout = { dma_on, 5'bXXXXX, dma_burst, dma_snr};
  96.         endcase
  97.  
  98.         // ports.v write access & dma_addr control
  99.         always @(posedge clk, negedge rst_n)
  100.         if( !rst_n ) // async reset
  101.         begin
  102.                 dma_on    <= 1'b0;
  103.                 dma_snr   <= 1'b0; // receive is less dangerous since it won't destroy SDcard info
  104.                 dma_burst <= 1'b0;
  105.         end
  106.         else // posedge clk
  107.         begin
  108.                 // dma_on control
  109.                 if( module_select && write_strobe && (regsel==_CST) )
  110.                 begin
  111.                         dma_on    <= din[7];
  112.                         dma_burst <= din[1];
  113.                         dma_snr   <= din[0];
  114.                 end
  115.                 else if( dma_finish )
  116.                 begin
  117.                         dma_on <= 1'b0;
  118.                 end
  119.  
  120.                 // dma_addr control
  121.                 if( dma_ack && dma_on )
  122.                         dma_addr <= dma_addr + 21'd1; // increment on beginning of DMA transfer
  123.                 else if( module_select && write_strobe )
  124.                 begin
  125.                         if( regsel==_HAD )
  126.                                 dma_addr[20:16] <= din[4:0];
  127.                         else if( regsel==_MAD )
  128.                                 dma_addr[15:8]  <= din[7:0];
  129.                         else if( regsel==_LAD )
  130.                                 dma_addr[7:0]   <= din[7:0];
  131.                 end
  132.         end
  133.  
  134.  
  135.  
  136. // fifo,dma,sd control FSMs/etc.
  137.        
  138.         reg init;
  139.         wire wr_stb,rd_stb;
  140.         wire wdone,rdone,empty;
  141.  
  142.         wire [7:0] fifo_wd; // data for FIFO to be written
  143.         wire [7:0] fido_rd; // data read from FIFO
  144.  
  145.         // MUX data to FIFO
  146.         assign fifo_wd       = dma_snr ? dma_rd  : sd_receiveddata;
  147.         // MUX data to SDcard
  148.         assign sd_datatosend = dma_snr ? fifo_rd : 8'hFF;
  149.        
  150.         // connect dma in to fifo out without muxing
  151.         assign dma_wd = fifo_rd;
  152.  
  153.         fifo512_oneshot fifo512_oneshot ( .clk(clk),
  154.                                           .rst_n(rst_n),
  155.  
  156.                                           .init(init),
  157.  
  158.                                           .wr_stb(wr_stb),
  159.                                           .rd_stb(rd_stb),
  160.  
  161.                                           .wdone(wdone),
  162.                                           .rdone(rdone),
  163.                                           .empty(empty),
  164.  
  165.                                           .wd(fifo_wd),
  166.                                           .rd(fifo_rd)
  167.                                         );
  168.         // fifo control
  169.         reg sd_wr_stb,sd_rd_stb;   // set in SD FSM
  170.         reg dma_wr_stb,dma_rd_stb; // set in DMA FSM
  171.         //     
  172.         assign wr_stb = sd_wr_stb | dma_wr_stb;
  173.         assign rd_stb = sd_rd_stb | dma_rd_stb;
  174.  
  175.         // dma control
  176.         wire dma_put_req;
  177.         wire dma_get_req;
  178.        
  179.         assign dma_req = dma_put_req | dma_get_req;
  180.  
  181.  
  182.  
  183.         reg sd_go; // start strobe for SD FSM
  184.         reg sd_idle; // whether SD FSM is idle
  185.  
  186.         reg dma_go;
  187.         reg dma_idle;
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.         // SD-card controlling FSM
  195.        
  196.         reg [2:0] sd_state, sd_next_state;
  197.        
  198.         localparam SD_IDLE   = 3'b000;
  199.         localparam SD_READ1  = 3'b100;
  200.         localparam SD_READ2  = 3'b101;
  201.         localparam SD_WRITE1 = 3'b110;
  202.         localparam SD_WRITE2 = 3'b111;
  203.        
  204.         always @(posedge clk, negedge rst_n)
  205.         begin
  206.                 if( !rst_n )
  207.                 begin
  208.                         sd_state = SD_IDLE;
  209.                 end
  210.                 else // posedge clk
  211.                 begin
  212.                         sd_state <= sd_next_state;
  213.                 end
  214.         end
  215.  
  216.         always @*
  217.         begin
  218.                 case( sd_state )
  219. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  220.                 SD_IDLE:begin
  221.                         if( sd_go )
  222.                         begin
  223.                                 if( sd_snr ) // send to SD
  224.                                 begin
  225.                                         sd_next_state = SD_WRITE1;
  226.                                 end
  227.                                 else // !sd_snr: read from SD
  228.                                 begin
  229.                                         sd_next_state = SD_READ1;
  230.                                 end
  231.                         end
  232.                         else
  233.                         begin
  234.                                 sd_next_state = SD_IDLE;
  235.                         end
  236.                 end
  237. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  238.                 SD_READ1:begin
  239.                         if( wdone )
  240.                         begin
  241.                                 sd_next_state = SD_IDLE;
  242.                         end
  243.                         else // !wdone - can still send bytes to the fifo
  244.                         begin
  245.                                 if( !sd_rdy ) // not ready with previous byte - wait here
  246.                                 begin
  247.                                         sd_next_state = SD_READ1;
  248.                                 end
  249.                                 else // sd_rdy - can proceed further
  250.                                 begin
  251.                                         sd_next_state = SD_READ2;
  252.                                 end
  253.                         end
  254.                 end
  255. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  256.                 SD_READ2:begin
  257.                         sd_next_state = SD_READ1;
  258.                 end
  259. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  260.                 SD_WRITE1:begin
  261.                         if( rdone )
  262.                         begin
  263.                                 sd_next_state = SD_IDLE;
  264.                         end
  265.                         else
  266.                         begin
  267.                                 if( sd_rdy && !empty ) // whether sd ready and we can take next byte from fifo
  268.                                 begin
  269.                                         sd_next_state = SD_WRITE2;
  270.                                 end
  271.                                 else // can't start next byte: wait
  272.                                 begin
  273.                                         sd_next_state = SD_WRITE1;
  274.                                 end
  275.                         end
  276.                 end
  277. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  278.                 SD_WRITE2:begin
  279.                         sd_next_state = SD_WRITE1;
  280.                 end
  281. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  282.                 default:begin
  283.                         sd_next_state = SD_IDLE;
  284.                 end
  285. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  286.                 endcase
  287.         end
  288.  
  289.         always @(posedge clk, negedge rst_n)
  290.         begin
  291.                 if( !rst_n )
  292.                 begin
  293.                         sd_wr_stb   = 1'b0;
  294.                         sd_rd_stb   = 1'b0;
  295.                         sd_start    = 1'b0;
  296.                         sd_override = 1'b0;
  297.                
  298.                         sd_idle     = 1'b0;
  299.                 end
  300.                 else // posedge clk
  301.                 begin
  302.                         case( sd_next_state )
  303. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  304.                         SD_IDLE:begin
  305.                                 sd_wr_stb   <= 1'b0;
  306.                                 sd_rd_stb   <= 1'b0;
  307.                                 sd_start    <= 1'b0;
  308.                                 sd_override <= 1'b0;
  309.                                
  310.                                 sd_idle     <= 1'b1;
  311.                         end
  312. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  313.                         SD_READ1:begin
  314.                                 sd_override <= 1'b1; // takeover SD card SPI iface
  315.                                 sd_start    <= 1'b0;
  316.                                 sd_wr_stb   <= 1'b0;
  317.                                
  318.                                 sd_idle     <= 1'b0;
  319.                         end
  320. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  321.                         SD_READ2:begin
  322.                                 sd_start  <= 1'b1; // trigger new SPI exchange
  323.                                 sd_wr_stb <= 1'b1; // trigger FIFO write
  324.                         end
  325. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  326.                         SD_WRITE1:begin
  327.                                 sd_override <= 1'b1;
  328.                                 sd_start    <= 1'b0;
  329.                                 sd_rd_str   <= 1'b0;
  330.                                
  331.                                 sd_idle     <= 1'b0;
  332.                         end
  333. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  334.                         SD_WRITE2:begin
  335.                                 sd_start  <= 1'b1;
  336.                                 sd_rd_stb <= 1'b1;
  337.                         end
  338. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  339.                         endcase
  340.                 end
  341.         end
  342.        
  343.  
  344.  
  345.  
  346.  
  347.  
  348.         // DMA-controlling FSM
  349.  
  350.         reg [3:0] dma_state, dma_next_state
  351.        
  352.         localparam DMA_IDLE
  353.         localparam DMA_PUT_WAIT
  354.         localparam DMA_PUT_RUN
  355.  
  356.         always @(posedge clk, negedge rst_n)
  357.         begin
  358.                 if( !rst_n )
  359.                 begin
  360.                         dma_state = DMA_IDLE;
  361.                 end
  362.                 else // posedge clk
  363.                 begin
  364.                         dma_state <= dma_next_state;
  365.                 end
  366.         end
  367.  
  368.         always @*
  369.         begin
  370.                 case( dma_state )
  371. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  372.                 DMA_IDLE:begin
  373.                         if( dma_go )
  374.                         begin
  375.                                 if( dma_snr )
  376.                                 begin
  377.                                         ........dma_state = DMA_GET_WAIT;
  378.                                 end
  379.                                 else // !dma_snr
  380.                                 begin
  381.                                         dma_next_state = DMA_PUT_WAIT;
  382.                                 end
  383.                         end
  384.                         else
  385.                         begin
  386.                                 dma_next_state = DMA_IDLE;
  387.                         end
  388.                 end
  389. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  390.                 DMA_PUT_WAIT:begin
  391.                         if( rdone )
  392.                         begin
  393.                                 dma_next_state = DMA_IDLE;
  394.                         end
  395.                         else // !rdone
  396.                         begin
  397.                                 if( !empty ) // fifo is not empty
  398.                                 begin
  399.                                         dma_next_state = DMA_PUT_RUN;
  400.                                 end
  401.                                 else // fifo empty
  402.                                 begin
  403.                                         dma_next_state = DMA_PUT_WAIT;
  404.                                 end
  405.                         end
  406.                 end
  407. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  408.                 DMA_PUT_RUN:begin
  409.                         if( rdone )
  410.                         begin
  411.                                 dma_next_state = DMA_IDLE;
  412.                         end
  413.                         else
  414.                         begin
  415.                                 if( empty )
  416.                                 begin
  417.                                         dma_next_state = DMA_PUT_WAIT;
  418.                                 end
  419.                                 else // !empty
  420.                                 begin
  421.                                         dma_next_state = DMA_PUT_RUN;
  422.                                 end
  423.                         end
  424.                 end
  425. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  426. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  427. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  428. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  429. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  430. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  431. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  432. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  433. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  434.                 endcase
  435.         end
  436.        
  437.         always @(posedge clk, negedge rst_n)
  438.         begin
  439.                 if( !rst_n )
  440.                 begin
  441.                
  442.                 end
  443.                 else // posedge clk
  444.                 begin
  445.                         case( dma_next_state )
  446. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  447. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  448. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  449. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  450. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  451. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  452. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  453. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  454. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  455. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  456. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  457. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  458. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  459. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  460. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  461. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  462. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  463. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  464. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  465.                         endcase
  466.                 end
  467.         end
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484.  
  485.  
  486.  
  487.  
  488.  
  489.  
  490.  
  491.  
  492.  
  493.  
  494.  
  495.  
  496.  
  497.  
  498. endmodule
  499.  
  500.  
  501.  
  502.  
  503. // this is "one-shot" fifo: after each 512 bytes both written and read back, it must be initialized by means of 'init'
  504. //
  505. module fifo512_oneshot(
  506.  
  507.         input  wire clk,
  508.         input  wire rst_n,
  509.        
  510.         input  wire init, // initializes fifo: wptr=rptr=0
  511.        
  512.         input  wire wr_stb, // write strobe: writes data from wd to the current wptr, increments wptr
  513.         input  wire rd_stb, // read strobe: increments rptr
  514.        
  515.         output wire wdone, // write done - all 512 bytes are written (end of write operation)
  516.         output wire rdone, // read done - all 512 bytes are read (end of read operation)
  517.         output wire empty, // fifo empty: when wptr==rptr (rd_stb must not be issued when empty is active, otherwise everytrhing desyncs)
  518.        
  519.         input  wire [7:0] wd, // data to be written
  520.         output wire [7:0] rd  // data just read from rptr address
  521. );
  522.  
  523.         reg [9:0] wptr;
  524.         reg [9:0] rptr;
  525.  
  526.         always @(posedge clk, negedge rst_n)
  527.         begin
  528.                 if( !rst_n )
  529.                 begin
  530.                         wptr = 10'd0;
  531.                         rptr = 10'd0;
  532.                 end
  533.                 else
  534.                 begin // posedge clk
  535.                
  536.                         if( init )
  537.                         begin
  538.                                 wptr <= 10'd0;
  539.                         end
  540.                         else if( wr_stb )
  541.                         begin
  542.                                 wptr <= wptr + 10'd1;
  543.                         end
  544.                
  545.                
  546.                         if( init )
  547.                         begin
  548.                                 rptr <= 10'd0;
  549.                         end
  550.                         else if( rd_stb )
  551.                         begin
  552.                                 rptr <= rptr + 10'd1;
  553.                         end
  554.                
  555.                 end
  556.         end
  557.  
  558.         assign wdone = wptr[9];
  559.         assign rdone = rptr[9];
  560.         assign empty = ( wptr==rptr );
  561.  
  562.  
  563.  
  564.         mem512b fifo512_oneshot_mem512b( .clk(clk),
  565.  
  566.                                          .rdaddr(rptr[8:0]),
  567.                                          .dataout(rd),
  568.  
  569.                                          .wraddr(wptr[8:0]),
  570.                                          .datain(wd),
  571.                                          .we(wr_stb)
  572.                                        );
  573. endmodule
  574.