acam_model.svh 3.49 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
`timescale 1ps/1ps




// R-Mode only!
module acam_model
  (
   input PuResN,
   input Alutrigger,
   input RefClk,

   input WRN,
   input RDN,
   input CSN,
   input OEN,

   input [3:0] Adr,
   input DStart,
   input DStop1,
   input DStop2,

   input TStart,
   input[8:1] TStop,

   input StartDis,
   input[4:1] StopDis,

   output IrFlag,
   output ErrFlag,

   output reg EF1,
   output LF1,

   inout[27:0] D

   /* sim-only */

   );

   parameter real g_rmode_resolution  = 80.9553ps / 3.0;
   parameter int g_verbose 	      = 1;

   const real c_empty_flag_delay       = 75ns;


   wire start_masked;
   wire stop1_masked;

   wire r_MasterAluTrig;
   wire r_StartDisStart;
     
   reg[27:0] RB[0:14];
   reg[27:0] DQ = 0;

   reg EF1_int 	= 1'b1;
   reg start_disabled_int;

   int rmode_start_offset;
   
   mailbox q_start, q_stop1;
   mailbox q_hit;
   
   int t 		      = 0;

  
   assign rmode_start_offset  = RB[5][17:0];
   
   always #(g_rmode_resolution) t <= t + 1;

   assign r_MasterAluTrig  = RB[5][23];
   assign r_StartDisStart  = RB[5][22];
   

   task master_reset;
      int i;
      
78 79 80
      q_start             = new(16384);
      q_stop1             = new(16384);
      q_hit               = new(16384);
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
      EF1                <= 1;
      start_disabled_int <= 0;

      for(i=0;i<15;i++)
        RB[i]             = 0;
      
      
   endtask // master_reset

   initial master_reset();
   
   
   always@(negedge PuResN) begin
      master_reset();
      end
   
   always@(posedge Alutrigger) begin
      if(r_MasterAluTrig)
	begin
	   int dummy;
	   
	   while(q_hit.num() > 0) q_hit.get(dummy);
	   
	   start_disabled_int <= 0;
//	   EF1		      <= 0;
	end
//	master_reset();
   end

   always@(negedge Alutrigger) begin
      if(r_MasterAluTrig)
	begin
//	   EF1		      <= 1;
	end
   end
   
//    
   

   always@(posedge DStart) 
     if(PuResN && !StartDis && !start_disabled_int) begin
	if(g_verbose)$display("acam::start %d", t);
	q_start.put(t);
	start_disabled_int <= r_StartDisStart;
	
     end

   always@(posedge DStop1) 
     if(PuResN && !StopDis[1]) begin
		if(g_verbose)$display("acam::stop1 %d", t);
	q_stop1.put(t);
     end
   

   always@(negedge WRN) if (!CSN && RDN)
     begin
	RB[Adr] <= D;
		if(g_verbose)$display("acam::write reg %x val %x\n", Adr, D);
     end
   
   always@(negedge RDN) if (!CSN && WRN)
     begin
		if(g_verbose)$display("acam::read reg %x val %x\n", Adr, RB[Adr]);     
	if(Adr == 8) begin
	   int hit;
	   
	   q_hit.try_get(hit);
	   DQ 	    <= hit;
	   
	end else
	  DQ <= RB[Adr];
     end
   
   
   always@(negedge PuResN) begin
      int i;
      for (i=0;i<14;i++) RB[i] <= 0;
   end

   assign D  = (!OEN)?DQ:28'bz;
   
   initial forever
     begin
	int t_start, t_stop1, n_starts, tmp, hit;

	#1;

	q_stop1.get(t_stop1);
	

	while(q_start.num() > 0) begin
	   q_start.peek(t_start);
	   
	   if(t_start < t_stop1)
	     begin
		q_start.get(tmp);
	     end 
	   else 
	     break;
	   end



	if(t_stop1 - t_start > 3780)
	  hit  =  (t_stop1 - t_start) - (128ns/g_rmode_resolution) + rmode_start_offset * 3;
	else
	  hit  = t_stop1 - t_start + rmode_start_offset * 3;

	
Tomasz Wlostowski's avatar
Tomasz Wlostowski committed
190
	if(g_verbose)$display("acam::hit1 %d t_stop1 %d t_start %d", hit, t_stop1, t_start);
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
	
	if(q_hit.num() == 0) begin
	  #(c_empty_flag_delay);
	end

	
	q_hit.put(hit);

	end 


   reg fifo_empty     =1;
   reg fifo_notempty  = 0;
   
   initial forever begin
      #1;
      
      if(q_hit.num() > 0)
	EF1 = #(12ns) 0;
      else
	EF1 = 1;
     
   end
   
   
   
   
   
endmodule // acam_model