lm32_trace.v

changeset 14
54dd95f89113
parent 13
e66ed0e9e2f8
child 15
27f96ec74b85
     1.1 --- a/lm32_trace.v	Sun Mar 06 19:23:51 2011 +0000
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,298 +0,0 @@
     1.4 -// =============================================================================
     1.5 -//                           COPYRIGHT NOTICE
     1.6 -// Copyright 2006 (c) Lattice Semiconductor Corporation
     1.7 -// ALL RIGHTS RESERVED
     1.8 -// This confidential and proprietary software may be used only as authorised by
     1.9 -// a licensing agreement from Lattice Semiconductor Corporation.
    1.10 -// The entire notice above must be reproduced on all authorized copies and
    1.11 -// copies may only be made to the extent permitted by a licensing agreement from
    1.12 -// Lattice Semiconductor Corporation.
    1.13 -//
    1.14 -// Lattice Semiconductor Corporation        TEL : 1-800-Lattice (USA and Canada)
    1.15 -// 5555 NE Moore Court                            408-826-6000 (other locations)
    1.16 -// Hillsboro, OR 97124                     web  : http://www.latticesemi.com/
    1.17 -// U.S.A                                   email: techsupport@latticesemi.com
    1.18 -// =============================================================================/
    1.19 -//                         FILE DETAILS
    1.20 -// Project          : LatticeMico32
    1.21 -// File             : lm32_trace.v
    1.22 -// Title            : PC Trace and associated logic.
    1.23 -// Dependencies     : lm32_include.v, lm32_functions.v
    1.24 -// Version          : 6.1.17
    1.25 -//                  : Initial Release
    1.26 -// Version          : 7.0SP2, 3.0
    1.27 -//                  : No Change
    1.28 -// Version          : 3.1
    1.29 -//                  : No Change
    1.30 -// =============================================================================
    1.31 -
    1.32 -`include "lm32_include.v"
    1.33 -`include "system_conf.v"
    1.34 -
    1.35 -`ifdef CFG_TRACE_ENABLED
    1.36 -module lm32_trace(
    1.37 -		  // ----- Inputs -------
    1.38 -		  clk_i,
    1.39 -		  rst_i,
    1.40 -		  stb_i,
    1.41 -		  we_i,
    1.42 -		  sel_i,
    1.43 -		  dat_i,
    1.44 -		  adr_i,
    1.45 -		  
    1.46 -		  trace_pc,
    1.47 -		  trace_eid,
    1.48 -		  trace_eret,
    1.49 -		  trace_bret,
    1.50 -		  trace_pc_valid,
    1.51 -		  trace_exception,
    1.52 -		  
    1.53 -		  // -- outputs
    1.54 -		  ack_o,
    1.55 -		  dat_o);
    1.56 -
    1.57 -   input clk_i;   
    1.58 -   input rst_i;   
    1.59 -   input stb_i;
    1.60 -   input we_i;   
    1.61 -   input [3:0] sel_i;
    1.62 -   input [`LM32_WORD_RNG] dat_i;
    1.63 -   input [`LM32_WORD_RNG] adr_i;
    1.64 -   input [`LM32_PC_RNG]   trace_pc;
    1.65 -   input [`LM32_EID_RNG]  trace_eid;
    1.66 -   input 		  trace_eret;
    1.67 -   input 		  trace_bret;
    1.68 -   input 		  trace_pc_valid;
    1.69 -   input 		  trace_exception;
    1.70 -   // -- outputs
    1.71 -   output 		  ack_o;
    1.72 -   output [`LM32_WORD_RNG] dat_o;
    1.73 -   reg 			   ovrflw;
    1.74 -   
    1.75 -   function integer clogb2;
    1.76 -      input [31:0] value;
    1.77 -      begin
    1.78 -	 for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1)
    1.79 -           value = value >> 1;
    1.80 -      end
    1.81 -   endfunction 
    1.82 -  
    1.83 -  // instantiate the trace memory
    1.84 -  parameter mem_data_width = `LM32_PC_WIDTH;
    1.85 -  parameter mem_addr_width = clogb2(`CFG_TRACE_DEPTH-1);
    1.86 -   
    1.87 -   wire [`LM32_PC_RNG] 	     trace_dat_o;
    1.88 -   wire [mem_addr_width-1:0] trace_raddr;
    1.89 -   wire [mem_addr_width-1:0] trace_waddr;
    1.90 -   reg  		     trace_we;
    1.91 -   wire 		     trace_be, trace_last;   
    1.92 -   wire 		     rw_creg = adr_i[12]; 
    1.93 -   
    1.94 -   lm32_ram #(.data_width    (mem_data_width),
    1.95 -	      .address_width (mem_addr_width)) 
    1.96 -     trace_mem (.read_clk  	(clk_i),
    1.97 -		.write_clk 	(clk_i),
    1.98 -		.reset     	(rst_i),
    1.99 -		.read_address 	(adr_i[mem_addr_width+1:2]),
   1.100 -		.write_address  (trace_waddr),
   1.101 -		.enable_read 	(`TRUE),
   1.102 -		.enable_write 	((trace_we | trace_be) & trace_pc_valid & !trace_last),
   1.103 -		.write_enable 	(`TRUE),
   1.104 -		.write_data   	(trace_pc),
   1.105 -		.read_data    	(trace_dat_o));
   1.106 -
   1.107 -   // trigger type & stop type
   1.108 -   //  trig_type [0] = start capture when bret
   1.109 -   //  trig_type [1] = start capture when eret
   1.110 -   //  trig_type [2] = start capture when PC within a range
   1.111 -   //  trig_type [3] = start when an exception happens (other than breakpoint)
   1.112 -   //  trig_type [4] = start when a breakpoint exception happens
   1.113 -
   1.114 -   
   1.115 -   reg [4:0]	        trig_type;	   // at address  0
   1.116 -   reg [4:0] 	        stop_type;         // at address 16   
   1.117 -   reg [`LM32_WORD_RNG] trace_len;   	   // at address  4
   1.118 -   reg [`LM32_WORD_RNG]   pc_low;	   // at address  8
   1.119 -   reg [`LM32_WORD_RNG]   pc_high;	   // at address 12
   1.120 -   reg 		        trace_start,trace_stop;
   1.121 -   reg 		        ack_o;
   1.122 -   reg 			mem_valid;   
   1.123 -   reg [`LM32_WORD_RNG] reg_dat_o;
   1.124 -   reg started;
   1.125 -   reg capturing;
   1.126 -   assign 		dat_o = (rw_creg ? reg_dat_o : trace_dat_o);
   1.127 -   
   1.128 -   initial begin
   1.129 -      trig_type <= 0;
   1.130 -      stop_type <= 0;
   1.131 -      trace_len <= 0;
   1.132 -      pc_low    <= 0;
   1.133 -      pc_high   <= 0;
   1.134 -      trace_start <= 0;
   1.135 -      trace_stop  <= 0;
   1.136 -      ack_o 	<= 0;
   1.137 -      reg_dat_o <= 0;
   1.138 -      mem_valid <= 0;
   1.139 -      started   <= 0;
   1.140 -      capturing <= 0;
   1.141 -   end
   1.142 -   
   1.143 -   // the host side control
   1.144 -   always @(posedge clk_i `CFG_RESET_SENSITIVITY)
   1.145 -     begin
   1.146 -	if (rst_i == `TRUE) begin
   1.147 -	   trig_type   <= 0;
   1.148 -	   trace_stop  <= 0;
   1.149 -	   trace_start <= 0;
   1.150 -	   pc_low      <= 0;
   1.151 -	   pc_high     <= 0;
   1.152 -	   ack_o       <= 0;
   1.153 -	end else begin
   1.154 -	   if (stb_i == `TRUE && ack_o == `FALSE) begin
   1.155 -	      if (rw_creg) begin // control register access
   1.156 -		 ack_o <= `TRUE;		    
   1.157 -		 if (we_i == `TRUE) begin
   1.158 -		    case ({adr_i[11:2],2'b0})
   1.159 -		      // write to trig type
   1.160 -		      12'd0:
   1.161 -			begin
   1.162 -			   if (sel_i[0]) begin
   1.163 -			      trig_type[4:0] <= dat_i[4:0];
   1.164 -                           end
   1.165 -                           if (sel_i[3]) begin
   1.166 -                              trace_start <= dat_i[31];
   1.167 -                              trace_stop  <= dat_i[30];
   1.168 -                           end
   1.169 -			end
   1.170 -		      12'd8:
   1.171 -			begin
   1.172 -			   if (sel_i[3]) pc_low[31:24] <= dat_i[31:24];
   1.173 -			   if (sel_i[2]) pc_low[23:16] <= dat_i[23:16];
   1.174 -			   if (sel_i[1]) pc_low[15:8]  <= dat_i[15:8];
   1.175 -			   if (sel_i[0]) pc_low[7:0]   <= dat_i[7:0];			 
   1.176 -			end
   1.177 -		      12'd12:
   1.178 -			begin
   1.179 -			   if (sel_i[3]) pc_high[31:24] <= dat_i[31:24];
   1.180 -			   if (sel_i[2]) pc_high[23:16] <= dat_i[23:16];
   1.181 -			   if (sel_i[1]) pc_high[15:8]  <= dat_i[15:8];
   1.182 -			   if (sel_i[0]) pc_high[7:0]   <= dat_i[7:0];			 
   1.183 -			end
   1.184 -		      12'd16:
   1.185 -                        begin
   1.186 -			   if (sel_i[0])begin
   1.187 -                               stop_type[4:0] <= dat_i[4:0];
   1.188 -                           end
   1.189 -                        end
   1.190 -		    endcase
   1.191 -		 end else begin // read control registers
   1.192 -		    case ({adr_i[11:2],2'b0})
   1.193 -		      // read the trig type
   1.194 -		      12'd0:
   1.195 -                        reg_dat_o <= {22'b1,capturing,mem_valid,ovrflw,trace_we,started,trig_type};
   1.196 -		      12'd4:
   1.197 -                        reg_dat_o <= trace_len;			 
   1.198 -		      12'd8:
   1.199 -			reg_dat_o <= pc_low;
   1.200 -		      12'd12:
   1.201 -			reg_dat_o <= pc_high;		      
   1.202 -		      default:
   1.203 -			reg_dat_o <= {27'b0,stop_type};
   1.204 -		    endcase
   1.205 -		 end // else: !if(we_i == `TRUE)		 
   1.206 -	      end else // read / write memory
   1.207 -		if (we_i == `FALSE) begin
   1.208 -		   ack_o <= `TRUE;
   1.209 -		end else
   1.210 -		  ack_o <= `FALSE;	      
   1.211 -	      // not allowed to write to trace memory
   1.212 -	   end else begin // if (stb_i == `TRUE)
   1.213 -	      trace_start  <= `FALSE;
   1.214 -	      trace_stop   <= `FALSE;
   1.215 -	      ack_o        <= `FALSE;	      
   1.216 -	   end // else: !if(stb_i == `TRUE)	   
   1.217 -	end // else: !if(rst_i == `TRUE)
   1.218 -     end 
   1.219 -   
   1.220 -   wire [`LM32_WORD_RNG] trace_pc_tmp = {trace_pc,2'b0};
   1.221 -   
   1.222 -   // trace state machine
   1.223 -   reg [2:0] tstate;
   1.224 -   wire      pc_in_range = {trace_pc,2'b0} >= pc_low &&
   1.225 -	                   {trace_pc,2'b0} <= pc_high;
   1.226 -   
   1.227 -   assign    trace_waddr = trace_len[mem_addr_width-1:0];
   1.228 -
   1.229 -   wire trace_begin = ((trig_type[0] & trace_bret) ||
   1.230 -		       (trig_type[1] & trace_eret) ||
   1.231 -		       (trig_type[2] & pc_in_range & trace_pc_valid) ||
   1.232 -		       (trig_type[3] & trace_exception & (trace_eid != `LM32_EID_BREAKPOINT)) ||
   1.233 -                       (trig_type[4] & trace_exception & (trace_eid == `LM32_EID_BREAKPOINT))
   1.234 -                      );
   1.235 -   
   1.236 -
   1.237 -   wire trace_end = (trace_stop  ||
   1.238 -		      (stop_type[0] & trace_bret) ||
   1.239 -		      (stop_type[1] & trace_eret) ||
   1.240 -		      (stop_type[2] & !pc_in_range & trace_pc_valid) ||
   1.241 -		      (stop_type[3] & trace_exception & (trace_eid != `LM32_EID_BREAKPOINT)) ||
   1.242 -                      (stop_type[4] & trace_exception & (trace_eid == `LM32_EID_BREAKPOINT))
   1.243 -                    );
   1.244 -
   1.245 -   assign trace_be = (trace_begin & (tstate == 3'd1));
   1.246 -   assign trace_last = (trace_stop & (tstate == 3'd2));
   1.247 -   
   1.248 -   always @(posedge clk_i `CFG_RESET_SENSITIVITY)
   1.249 -     begin
   1.250 -	if (rst_i == `TRUE) begin
   1.251 -	   tstate    <= 0;
   1.252 -	   trace_we  <= 0;
   1.253 -	   trace_len <= 0;	   
   1.254 -	   ovrflw    <= `FALSE;
   1.255 -	   mem_valid <= 0;
   1.256 -           started   <= 0;
   1.257 -           capturing <= 0;
   1.258 -	end else begin
   1.259 -	   case (tstate)
   1.260 -	   3'd0:
   1.261 -	     // start capture	     
   1.262 -	     if (trace_start) begin
   1.263 -		tstate <= 3'd1;
   1.264 -		mem_valid <= 0;
   1.265 -                started   <= 1;
   1.266 -	     end
   1.267 -	   3'd1:
   1.268 -	     begin
   1.269 -		// wait for trigger
   1.270 -		if (trace_begin) begin
   1.271 -                   capturing <= 1;
   1.272 -		   tstate    <= 3'd2;
   1.273 -		   trace_we  <= `TRUE;
   1.274 -		   trace_len <= 0;		
   1.275 -		   ovrflw    <= `FALSE;			      
   1.276 -		end
   1.277 -	     end // case: 3'd1	     
   1.278 -
   1.279 -	   3'd2:
   1.280 -	     begin
   1.281 -		if (trace_pc_valid) begin
   1.282 -		   if (trace_len[mem_addr_width])
   1.283 -		     trace_len <= 0;
   1.284 -		   else
   1.285 -		     trace_len <= trace_len + 1;
   1.286 -		end
   1.287 -		if (!ovrflw) ovrflw <= trace_len[mem_addr_width];		
   1.288 -		// wait for stop condition
   1.289 -		if (trace_end) begin
   1.290 -		   tstate    <= 3'd0;
   1.291 -		   trace_we  <= 0;
   1.292 -		   mem_valid <= 1;
   1.293 -                   started   <= 0;
   1.294 -                   capturing <= 0;
   1.295 -		end
   1.296 -	     end // case: 3'd2
   1.297 -	   endcase
   1.298 -	end // else: !if(rst_i == `TRUE)
   1.299 -     end
   1.300 -endmodule
   1.301 -`endif