Subversion Repositories pentevo

Rev

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

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