Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. `include "../include/tune.v"
  2.  
  3. // PentEvo project (c) NedoPC 2008-2009
  4. //
  5. // DRAM controller. performs accesses to DRAM.
  6. //
  7. // state:          | RD1   | RD2   | RD3   | RD4   | WR1   | WR2   | WR3   | WR4   | RFSH1 | RFSH2 | RFSH3 | RFSH4 |
  8. // clk: ___/```\___/```\___/```\___/```\___/```\___/```\___/```\___/```\___/```\___/```\___/```\___/```\___/```\___/```\__
  9. //                 |      READ CYCLE               |      WRITE CYCLE              |      REFRESH CYCLE            |
  10. // ras: ```````````````````\_______________/```````````````\_______________/```````````````````````\_______________/
  11. // cas: ```````````````````````````\_______________/```````````````\_______________/```````\_______________/````````
  12. // ra:                 |  row  | column|               |  row  | column|
  13. // rd:     XXXXXXXXXXXXXXXXXXXXXXXXX<read data read|  write data write data write  |
  14. // rwe:   `````````````````````````````````````````\_______________________________/````````````````````````````````
  15. // req:  __/```````\_______________________/```````\________________________________________________________________
  16. // rnw:  XX/```````\XXXXXXXXXXXXXXXXXXXXXXX\_______/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  17. // cbeg: __________/```````\_______________________/```````\_______________________/```````\_______________________/
  18. // rrdy: __________________________________/```````\________________________________________________________________
  19. // addr: XX< addr  >XXXXXXXXXXXXXXXXXXXXXXX< addr  >XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  20. //wrdata:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX< write >XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  21. //rddata:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX< read  >XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  22. //
  23. // comments:
  24. // rucas_n, rlcas_n, rras0_n, rras1_n, rwe_n could be made 'fast output register'
  25. // ra[] couldn't be such in acex1k, because output registers could be all driven only by
  26. //  single clock polarity (and here they are driven by negative edge, while CAS/RAS by positive)
  27. //
  28. // rst_n is resynced before use and acts as req inhibit. so while in reset, dram regenerates and isn't corrupted
  29.  
  30. module dram(
  31.  
  32.         input clk,
  33.         input rst_n, // shut down accesses, remain refresh
  34.  
  35.         output reg [9:0] ra, // to the DRAM pins
  36.         inout     [15:0] rd, // .              .
  37.                              // .              .
  38.         output reg rwe_n,    // .              .
  39.         output reg rucas_n,  // .              .
  40.         output reg rlcas_n,  // .              .
  41.         output reg rras0_n,  // .              .
  42.         output reg rras1_n,  // to the DRAM pins
  43.  
  44.         input [20:0] addr, // access address of 16bit word: addr[0] selects between rras0_n and rras1_n,
  45.                            // addr[10:1] goes to row address, addr[20:11] goes to column address
  46.  
  47.         input req,         // request for read/write cycle
  48.         input rnw,         // READ/nWRITE (=1: read, =0: write)
  49.  
  50.         output reg cbeg,       // cycle begin (any including refresh), can be used for synchronizing
  51.         output reg rrdy,       // Read data ReaDY
  52.  
  53.         output reg [15:0] rddata, // data just read
  54.  
  55.         input  [15:0] wrdata, // data to be written
  56.         input   [1:0] bsel    // positive byte select for write: bsel[0] is for wrdata[7:0], bsel[1] is for wrdata[15:8]
  57.  
  58.  
  59. );
  60.  
  61.         reg [1:0] rst_sync;
  62.         wire reset;
  63.         wire int_req;
  64.  
  65.         reg [20:0] int_addr;
  66.         reg [15:0] int_wrdata;
  67.         reg  [1:0] int_bsel;
  68.  
  69.  
  70.         reg rfsh_alt; // we must alternate chips in refresh cycles to lower total heating
  71.  
  72.  
  73.  
  74.         reg [3:0] state;
  75.         reg [3:0] next_state;
  76.  
  77.         localparam RD1   = 0;
  78.         localparam RD2   = 1;
  79.         localparam RD3   = 2;
  80.         localparam RD4   = 3;
  81.         localparam WR1   = 4;
  82.         localparam WR2   = 5;
  83.         localparam WR3   = 6;
  84.         localparam WR4   = 7;
  85.         localparam RFSH1 = 8;
  86.         localparam RFSH2 = 9;
  87.         localparam RFSH3 = 10;
  88.         localparam RFSH4 = 11;
  89.  
  90.  
  91.  
  92.         initial
  93.         begin
  94.                 state = RFSH1; // for simulation only!
  95.                 rfsh_alt = 1'b0;
  96.         end
  97.  
  98.  
  99.         always @(posedge clk)
  100.         begin
  101.                 state <= next_state;
  102.         end
  103.  
  104.         always @*
  105.                 case( state )
  106.  
  107.                 RD1:
  108.                         next_state = RD2;
  109.                 RD2:
  110.                         next_state = RD3;
  111.                 RD3:
  112.                         next_state = RD4;
  113.                 RD4:
  114.                         if( !int_req )
  115.                                 next_state = RFSH1;
  116.                         else
  117.                                 next_state = rnw?RD1:WR1;
  118.  
  119.                 WR1:
  120.                         next_state = WR2;
  121.                 WR2:
  122.                         next_state = WR3;
  123.                 WR3:
  124.                         next_state = WR4;
  125.                 WR4:
  126.                         if( !int_req )
  127.                                 next_state = RFSH1;
  128.                         else
  129.                                 next_state = rnw?RD1:WR1;
  130.  
  131.  
  132.                 RFSH1:
  133.                         next_state = RFSH2;
  134.                 RFSH2:
  135.                         next_state = RFSH3;
  136.                 RFSH3:
  137.                         next_state = RFSH4;
  138.                 RFSH4:
  139.                         if( !int_req )
  140.                                 next_state = RFSH1;
  141.                         else
  142.                                 next_state = rnw?RD1:WR1;
  143.  
  144.                 endcase
  145.  
  146.  
  147.         // incoming data latching
  148.         always @(posedge clk)
  149.         begin
  150.                 if( (state==RD4) || (state==WR4) || (state==RFSH4) )
  151.                 begin
  152.                         int_addr   <= addr;
  153.                         int_wrdata <= wrdata;
  154.                         int_bsel   <= bsel;
  155.                 end
  156.         end
  157.  
  158.         // WE control
  159.         always @(posedge clk)
  160.         begin
  161.                 if( (next_state==WR1) || (next_state==WR2) || (next_state==WR3) || (next_state==WR4) )
  162.                         rwe_n <= 1'b0;
  163.                 else
  164.                         rwe_n <= 1'b1;
  165.         end
  166.  
  167.  
  168.         // RAS/CAS sequencing
  169.         always @(posedge clk)
  170.         begin
  171.                 case( state )
  172. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  173. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  174.                 RD1:
  175.                 begin
  176.                         rras0_n <= int_addr[0];
  177.                         rras1_n <= ~int_addr[0];
  178.                 end
  179. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  180.                 RD2:
  181.                 begin
  182.                         rucas_n <= 1'b0;
  183.                         rlcas_n <= 1'b0;
  184.                 end
  185. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  186.                 RD3:
  187.                 begin
  188.                         rras0_n <= 1'b1;
  189.                         rras1_n <= 1'b1;
  190.                 end
  191. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  192.                 RD4:
  193.                 begin
  194.                         rras0_n <= 1'b1;
  195.                         rras1_n <= 1'b1;
  196.                         rucas_n <= 1'b1;
  197.                         rlcas_n <= 1'b1;
  198.                 end
  199. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  200. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  201.                 WR1:
  202.                 begin
  203.                         rras0_n <= int_addr[0];
  204.                         rras1_n <= ~int_addr[0];
  205.                 end
  206. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  207.                 WR2:
  208.                 begin
  209.                         rucas_n <= ~int_bsel[1];
  210.                         rlcas_n <= ~int_bsel[0];
  211.                 end
  212. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  213.                 WR3:
  214.                 begin
  215.                         rras0_n <= 1'b1;
  216.                         rras1_n <= 1'b1;
  217.                 end
  218. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  219.                 WR4:
  220.                 begin
  221.                         rras0_n <= 1'b1;
  222.                         rras1_n <= 1'b1;
  223.                         rucas_n <= 1'b1;
  224.                         rlcas_n <= 1'b1;
  225.                 end
  226. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  227. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  228.                 RFSH1:
  229.                 begin
  230.                         rucas_n <= 1'b0;
  231.                         rlcas_n <= 1'b0;
  232.                 end
  233. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  234.                 RFSH2:
  235.                 begin
  236.                         rras0_n <=  rfsh_alt;
  237.                         rras1_n <= ~rfsh_alt;
  238.  
  239.                         rfsh_alt <= ~rfsh_alt;
  240.                 end
  241. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  242.                 RFSH3:
  243.                 begin
  244.                         rucas_n <= 1'b1;
  245.                         rlcas_n <= 1'b1;
  246.                 end
  247. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  248.                 RFSH4:
  249.                 begin
  250.                         rras0_n <= 1'b1;
  251.                         rras1_n <= 1'b1;
  252.                         rucas_n <= 1'b1;
  253.                         rlcas_n <= 1'b1;
  254.                 end
  255. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  256. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  257.                 endcase
  258.         end
  259.  
  260.  
  261.         // row/column address multiplexing
  262.         always @(negedge clk)
  263.         begin
  264.                 if( (state==RD1) || (state==WR1) )
  265.                         ra <= int_addr[10:1];
  266.                 else
  267.                         ra <= int_addr[20:11];
  268.         end
  269.  
  270.  
  271.         // DRAM data bus control
  272.         assign rd = rwe_n ? 16'hZZZZ : int_wrdata;
  273.  
  274.  
  275.         // read data from DRAM
  276.         always @(posedge clk)
  277.         begin
  278.                 if( state==RD3 )
  279.                         rddata <= rd;
  280.         end
  281.  
  282.  
  283.         // cbeg and rrdy control
  284.         always @(posedge clk)
  285.         begin
  286.                 if( (state==RD4) || (state==WR4) || (state==RFSH4) )
  287.                         cbeg <= 1'b1;
  288.                 else
  289.                         cbeg <= 1'b0;
  290.  
  291.  
  292.             if( state==RD3 )
  293.                 rrdy <= 1'b1;
  294.             else
  295.                 rrdy <= 1'b0;
  296.         end
  297.  
  298.  
  299.         // reset must be synchronous here in order to preserve
  300.         // DRAM state while other modules reset, but we have only
  301.         // asynchronous one globally. so we must re-synchronize it
  302.         // and use it as 'DRAM operation enable'. when in reset,
  303.         // controller ignores req signal and generates only refresh cycles
  304.         always @(posedge clk)
  305.                 rst_sync[1:0] <= { rst_sync[0], ~rst_n };
  306.  
  307.         assign reset = rst_sync[1];
  308.  
  309.         assign int_req = req & (~reset);
  310.  
  311. endmodule
  312.