acam_model.svh 3.87 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
`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;
77 78 79

      if(g_verbose) $display("Acam::MasterReset");
      
80
      
81 82 83
      q_start             = new(16384);
      q_stop1             = new(16384);
      q_hit               = new(16384);
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
      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
   
//    
   
122 123
   time t_prev;
   
124 125
   always@(posedge DStart) 
     if(PuResN && !StartDis && !start_disabled_int) begin
126
//	if(g_verbose)$display("acam::start %d", t);
127
	q_start.put(t);
128 129 130
//        $display("StartEvt %d [delta %d]\n", t, t-t_prev);
//        t_prev = t;
        
131 132 133 134 135 136
	start_disabled_int <= r_StartDisStart;
	
     end

   always@(posedge DStop1) 
     if(PuResN && !StopDis[1]) begin
137
	if(g_verbose)$display("acam::stop1 %d", t);
138 139 140 141 142 143 144 145 146 147 148 149
	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
150
	if(g_verbose)$display("acam::read reg %x val %x\n", Adr, RB[Adr]);     
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
	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

167 168 169 170 171
   assign D  = (!CSN && !RDN)?DQ:28'bz;

   
   

172
   
173
   always@(posedge RefClk)
174
     begin
175
 
176 177
	int t_start, t_stop1, n_starts, tmp, hit;

178 179 180 181 182 183 184 185 186 187 188 189 190 191
        if(q_stop1.num() > 0)
          begin
	     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
192 193
	     if(t_stop1 - t_start > 8520)
	       hit  =  (t_stop1 - t_start) - (256ns/g_rmode_resolution) + rmode_start_offset * 3;
194 195 196 197
	     else
	       hit  = t_stop1 - t_start + rmode_start_offset * 3;

	     if(g_verbose)$display("acam::hit1 %d t_stop1 %d t_start %d", hit, t_stop1, t_start);
198
	
199 200 201
	     if(q_hit.num() == 0) begin
	        #(c_empty_flag_delay);
	     end
202
	
203 204 205 206 207
	     q_hit.put(hit);
	  end // if (q_stop1.num() > 0)
     end // always@ (posedge RefClk)
   
   
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
   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