Subversion Repositories pentevo

Rev

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

  1. `include "../include/tune.v"
  2.  
  3. module drammem(
  4.         input   [9:0] ma,
  5.         inout [15:0] d,
  6.         input ras_n,
  7.         input ucas_n,
  8.         input lcas_n,
  9.         input we_n
  10. );
  11.  
  12.         parameter _verbose_ = 1;
  13.         parameter _add_to_addr_ = 0;
  14.         parameter _filter_out_ = 32'h91;
  15.         parameter _init_ = 1;
  16.  
  17.         reg [15:0] array [0:1048575];
  18.         reg [15:0] dout;
  19.  
  20.         reg [19:0] addr;
  21.  
  22.         wire cas_n;
  23.  
  24.         wire idle;
  25.  
  26.         reg was_ras;
  27.         reg was_cas;
  28.         reg ready;
  29.  
  30.  
  31.  
  32.         initial
  33.         begin : clear_mem
  34.                 integer i;
  35.  
  36.                 if( _init_ )
  37.                 begin
  38.                         for(i=0;i<1048576;i=i+1)
  39.                                 array[i] = 16'hDEAD;
  40.                 end
  41.         end
  42.  
  43.  
  44.  
  45.  
  46.  
  47.         always @(negedge ras_n)
  48.                 addr[9:0] <= ma[9:0];
  49.  
  50.         assign cas_n = ucas_n & lcas_n;
  51.         always @(negedge cas_n)
  52.         begin
  53.                 addr[19:10] <= ma[9:0];
  54.         end
  55.  
  56.         always @(posedge cas_n, negedge cas_n)
  57.                 ready <= ~cas_n; // to introduce delta-cycle in ready to allow capturing of CAS address before proceeding data
  58.  
  59.  
  60.         assign idle = ras_n & cas_n;
  61.  
  62.         always @(negedge ras_n, posedge idle)
  63.         begin
  64.                 if( idle )
  65.                         was_ras <= 1'b0;
  66.                 else // negedge ras_n
  67.                         was_ras <= 1'b1;
  68.         end
  69.  
  70.         always @(negedge cas_n, posedge idle)
  71.         begin
  72.                 if( idle )
  73.                         was_cas <= 1'b0;
  74.                 else
  75.                         if( was_ras )
  76.                                 was_cas <= 1'b1;
  77.         end
  78.  
  79.  
  80.  
  81.  
  82.  
  83.         assign d = dout;
  84.  
  85.         always @*
  86.         begin
  87.                 if( ready && was_ras && was_cas && we_n && (~idle) ) // idle here is to prevent races at the end of all previous signals, which cause redundant read at the end of write
  88.                 begin
  89.                         dout = array[addr];
  90. `ifdef DRAMMEM_VERBOSE
  91.                         if( _verbose_ == 1 )
  92.                         begin
  93.                                 if( addr != _filter_out_ )
  94.                                         $display("DRAM read at %t: ($%h)=>$%h",$time,addr*2+_add_to_addr_,dout);
  95.                         end
  96. `endif
  97.                 end
  98.                 else
  99.                 begin
  100.                         dout = 16'hZZZZ;
  101.                 end
  102.         end
  103.  
  104.  
  105.         always @*
  106.                 if( ready && was_ras && was_cas && (~we_n) && (~idle) )
  107.                 begin
  108.                         if( ~ucas_n )
  109.                                 array[addr][15:8] = d[15:8];
  110.  
  111.                         if( ~lcas_n )
  112.                                 array[addr][7:0] = d[7:0];
  113.  
  114. `ifdef DRAMMEM_VERBOSE
  115.                         if( _verbose_ == 1 )
  116.                         begin
  117.                                 if( addr != _filter_out_ )
  118.                                         $display("DRAM written at %t: ($%h)<=$%h.$%h",$time,addr*2+_add_to_addr_,ucas_n?8'hXX:d[15:8],lcas_n?8'hXX:d[7:0]);
  119.                         end
  120. `endif
  121.                 end
  122.  
  123.  
  124.  
  125.  
  126. endmodule
  127.  
  128.