Subversion Repositories pentevo

Rev

Rev 425 | Blame | Compare with Previous | 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. `ifdef SIMULATE
  100.         always @(posedge clk)
  101.         begin
  102.                 if( req && !rnw && (state==RD4 || state==WR4 || state==RFSH4) )
  103.                 begin
  104.                         $display("written word %x mask %x to address %x",wrdata&{ {8{bsel[1]}}, {8{bsel[0]}} },{ {8{bsel[1]}}, {8{bsel[0]}} },addr);
  105.                 end
  106.         end
  107. `endif
  108. */
  109.  
  110.         always @(posedge clk)
  111.         begin
  112.                 state <= next_state;
  113.         end
  114.  
  115.         always @*
  116.                 case( state )
  117.  
  118.                 RD1:
  119.                         next_state = RD2;
  120.                 RD2:
  121.                         next_state = RD3;
  122.                 RD3:
  123.                         next_state = RD4;
  124.                 RD4:
  125.                         if( !int_req )
  126.                                 next_state = RFSH1;
  127.                         else
  128.                                 next_state = rnw?RD1:WR1;
  129.  
  130.                 WR1:
  131.                         next_state = WR2;
  132.                 WR2:
  133.                         next_state = WR3;
  134.                 WR3:
  135.                         next_state = WR4;
  136.                 WR4:
  137.                         if( !int_req )
  138.                                 next_state = RFSH1;
  139.                         else
  140.                                 next_state = rnw?RD1:WR1;
  141.  
  142.  
  143.                 RFSH1:
  144.                         next_state = RFSH2;
  145.                 RFSH2:
  146.                         next_state = RFSH3;
  147.                 RFSH3:
  148.                         next_state = RFSH4;
  149.                 RFSH4:
  150.                         if( !int_req )
  151.                                 next_state = RFSH1;
  152.                         else
  153.                                 next_state = rnw?RD1:WR1;
  154.  
  155.                 endcase
  156.  
  157.  
  158.         // incoming data latching
  159.         always @(posedge clk)
  160.         begin
  161.                 if( (state==RD4) || (state==WR4) || (state==RFSH4) )
  162.                 begin
  163.                         int_addr   <= addr;
  164.                         int_wrdata <= wrdata;
  165.                         int_bsel   <= bsel;
  166.                 end
  167.         end
  168.  
  169.         // WE control
  170.         always @(posedge clk)
  171.         begin
  172.                 if( (next_state==WR1) || (next_state==WR2) || (next_state==WR3) || (next_state==WR4) )
  173.                         rwe_n <= 1'b0;
  174.                 else
  175.                         rwe_n <= 1'b1;
  176.         end
  177.  
  178.  
  179.         // RAS/CAS sequencing
  180.         always @(posedge clk)
  181.         begin
  182.                 case( state )
  183. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  184. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  185.                 RD1:
  186.                 begin
  187.                         rras0_n <= int_addr[0];
  188.                         rras1_n <= ~int_addr[0];
  189.                 end
  190. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  191.                 RD2:
  192.                 begin
  193.                         rucas_n <= 1'b0;
  194.                         rlcas_n <= 1'b0;
  195.                 end
  196. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  197.                 RD3:
  198.                 begin
  199.                         rras0_n <= 1'b1;
  200.                         rras1_n <= 1'b1;
  201.                 end
  202. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  203.                 RD4:
  204.                 begin
  205.                         rras0_n <= 1'b1;
  206.                         rras1_n <= 1'b1;
  207.                         rucas_n <= 1'b1;
  208.                         rlcas_n <= 1'b1;
  209.                 end
  210. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  211. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  212.                 WR1:
  213.                 begin
  214.                         rras0_n <= int_addr[0];
  215.                         rras1_n <= ~int_addr[0];
  216.                 end
  217. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  218.                 WR2:
  219.                 begin
  220.                         rucas_n <= ~int_bsel[1];
  221.                         rlcas_n <= ~int_bsel[0];
  222.                 end
  223. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  224.                 WR3:
  225.                 begin
  226.                         rras0_n <= 1'b1;
  227.                         rras1_n <= 1'b1;
  228.                 end
  229. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  230.                 WR4:
  231.                 begin
  232.                         rras0_n <= 1'b1;
  233.                         rras1_n <= 1'b1;
  234.                         rucas_n <= 1'b1;
  235.                         rlcas_n <= 1'b1;
  236.                 end
  237. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  238. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  239.                 RFSH1:
  240.                 begin
  241.                         rucas_n <= 1'b0;
  242.                         rlcas_n <= 1'b0;
  243.                 end
  244. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  245.                 RFSH2:
  246.                 begin
  247.                         rras0_n <=  rfsh_alt;
  248.                         rras1_n <= ~rfsh_alt;
  249.  
  250.                         rfsh_alt <= ~rfsh_alt;
  251.                 end
  252. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  253.                 RFSH3:
  254.                 begin
  255.                         rucas_n <= 1'b1;
  256.                         rlcas_n <= 1'b1;
  257.                 end
  258. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  259.                 RFSH4:
  260.                 begin
  261.                         rras0_n <= 1'b1;
  262.                         rras1_n <= 1'b1;
  263.                         rucas_n <= 1'b1;
  264.                         rlcas_n <= 1'b1;
  265.                 end
  266. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  267. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  268.                 endcase
  269.         end
  270.  
  271.  
  272.         // row/column address multiplexing
  273.         always @(negedge clk)
  274.         begin
  275.                 if( (state==RD1) || (state==WR1) )
  276.                         ra <= int_addr[10:1];
  277.                 else
  278.                         ra <= int_addr[20:11];
  279.         end
  280.  
  281.  
  282.         // DRAM data bus control
  283.         assign rd = rwe_n ? 16'hZZZZ : int_wrdata;
  284.  
  285.  
  286.         // read data from DRAM
  287.         always @(posedge clk)
  288.         begin
  289.                 if( state==RD3 )
  290.                         rddata <= rd;
  291.         end
  292.  
  293.  
  294.         // cbeg and rrdy control
  295.         always @(posedge clk)
  296.         begin
  297.                 if( (state==RD4) || (state==WR4) || (state==RFSH4) )
  298.                         cbeg <= 1'b1;
  299.                 else
  300.                         cbeg <= 1'b0;
  301.  
  302.  
  303.             if( state==RD3 )
  304.                 rrdy <= 1'b1;
  305.             else
  306.                 rrdy <= 1'b0;
  307.         end
  308.  
  309.  
  310.         // reset must be synchronous here in order to preserve
  311.         // DRAM state while other modules reset, but we have only
  312.         // asynchronous one globally. so we must re-synchronize it
  313.         // and use it as 'DRAM operation enable'. when in reset,
  314.         // controller ignores req signal and generates only refresh cycles
  315.         always @(posedge clk)
  316.                 rst_sync[1:0] <= { rst_sync[0], ~rst_n };
  317.  
  318.         assign reset = rst_sync[1];
  319.  
  320.         assign int_req = req & (~reset);
  321.  
  322. endmodule
  323.