lm32_trace.v

Sat, 06 Aug 2011 01:26:56 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sat, 06 Aug 2011 01:26:56 +0100
changeset 27
d6c693415d59
parent 26
73de224304c1
permissions
-rwxr-xr-x

remove synthesis delay entities to ease merge

     1 //   ==================================================================
     2 //   >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
     3 //   ------------------------------------------------------------------
     4 //   Copyright (c) 2006-2011 by Lattice Semiconductor Corporation
     5 //   ALL RIGHTS RESERVED 
     6 //   ------------------------------------------------------------------
     7 //
     8 //   IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM.
     9 //
    10 //   Permission:
    11 //
    12 //      Lattice Semiconductor grants permission to use this code
    13 //      pursuant to the terms of the Lattice Semiconductor Corporation
    14 //      Open Source License Agreement.  
    15 //
    16 //   Disclaimer:
    17 //
    18 //      Lattice Semiconductor provides no warranty regarding the use or
    19 //      functionality of this code. It is the user's responsibility to
    20 //      verify the userís design for consistency and functionality through
    21 //      the use of formal verification methods.
    22 //
    23 //   --------------------------------------------------------------------
    24 //
    25 //                  Lattice Semiconductor Corporation
    26 //                  5555 NE Moore Court
    27 //                  Hillsboro, OR 97214
    28 //                  U.S.A
    29 //
    30 //                  TEL: 1-800-Lattice (USA and Canada)
    31 //                         503-286-8001 (other locations)
    32 //
    33 //                  web: http://www.latticesemi.com/
    34 //                  email: techsupport@latticesemi.com
    35 //
    36 //   --------------------------------------------------------------------
    37 //                         FILE DETAILS
    38 // Project          : LatticeMico32
    39 // File             : lm32_trace.v
    40 // Title            : PC Trace and associated logic.
    41 // Dependencies     : lm32_include.v, lm32_functions.v
    42 // Version          : 6.1.17
    43 //                  : Initial Release
    44 // Version          : 7.0SP2, 3.0
    45 //                  : No Change
    46 // Version          : 3.1
    47 //                  : No Change
    48 // Version          : 3.7
    49 //                  : Removed syntax error.
    50 // =============================================================================
    52 `include "lm32_include.v"
    53 `include "system_conf.v"
    55 `ifdef CFG_TRACE_ENABLED
    56 module lm32_trace(
    57 		  // ----- Inputs -------
    58 		  clk_i,
    59 		  rst_i,
    60 		  stb_i,
    61 		  we_i,
    62 		  sel_i,
    63 		  dat_i,
    64 		  adr_i,
    66 		  trace_pc,
    67 		  trace_eid,
    68 		  trace_eret,
    69 		  trace_bret,
    70 		  trace_pc_valid,
    71 		  trace_exception,
    73 		  // -- outputs
    74 		  ack_o,
    75 		  dat_o);
    77    input clk_i;   
    78    input rst_i;   
    79    input stb_i;
    80    input we_i;   
    81    input [3:0] sel_i;
    82    input [`LM32_WORD_RNG] dat_i;
    83    input [`LM32_WORD_RNG] adr_i;
    84    input [`LM32_PC_RNG]   trace_pc;
    85    input [`LM32_EID_RNG]  trace_eid;
    86    input 		  trace_eret;
    87    input 		  trace_bret;
    88    input 		  trace_pc_valid;
    89    input 		  trace_exception;
    90    // -- outputs
    91    output 		  ack_o;
    92    output [`LM32_WORD_RNG] dat_o;
    93    reg 			   ovrflw;
    95    function integer clogb2;
    96       input [31:0] value;
    97       begin
    98 	 for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1)
    99            value = value >> 1;
   100       end
   101    endfunction 
   103   // instantiate the trace memory
   104   parameter mem_data_width = `LM32_PC_WIDTH;
   105   parameter mem_addr_width = clogb2(`CFG_TRACE_DEPTH-1);
   107    wire [`LM32_PC_RNG] 	     trace_dat_o;
   108    wire [mem_addr_width-1:0] trace_raddr;
   109    wire [mem_addr_width-1:0] trace_waddr;
   110    reg  		     trace_we;
   111    wire 		     trace_be, trace_last;   
   112    wire 		     rw_creg = adr_i[12]; 
   114    lm32_ram #(.data_width    (mem_data_width),
   115 	      .address_width (mem_addr_width)) 
   116      trace_mem (.read_clk  	(clk_i),
   117 		.write_clk 	(clk_i),
   118 		.reset     	(rst_i),
   119 		.read_address 	(adr_i[mem_addr_width+1:2]),
   120 		.write_address  (trace_waddr),
   121 		.enable_read 	(`TRUE),
   122 		.enable_write 	((trace_we | trace_be) & trace_pc_valid & !trace_last),
   123 		.write_enable 	(`TRUE),
   124 		.write_data   	(trace_pc),
   125 		.read_data    	(trace_dat_o));
   127    // trigger type & stop type
   128    //  trig_type [0] = start capture when bret
   129    //  trig_type [1] = start capture when eret
   130    //  trig_type [2] = start capture when PC within a range
   131    //  trig_type [3] = start when an exception happens (other than breakpoint)
   132    //  trig_type [4] = start when a breakpoint exception happens
   135    reg [4:0]	        trig_type;	   // at address  0
   136    reg [4:0] 	        stop_type;         // at address 16   
   137    reg [`LM32_WORD_RNG] trace_len;   	   // at address  4
   138    reg [`LM32_WORD_RNG]   pc_low;	   // at address  8
   139    reg [`LM32_WORD_RNG]   pc_high;	   // at address 12
   140    reg 		        trace_start,trace_stop;
   141    reg 		        ack_o;
   142    reg 			mem_valid;   
   143    reg [`LM32_WORD_RNG] reg_dat_o;
   144    reg started;
   145    reg capturing;
   146    assign 		dat_o = (rw_creg ? reg_dat_o : trace_dat_o);
   148    initial begin
   149       trig_type <= 0;
   150       stop_type <= 0;
   151       trace_len <= 0;
   152       pc_low    <= 0;
   153       pc_high   <= 0;
   154       trace_start <= 0;
   155       trace_stop  <= 0;
   156       ack_o 	<= 0;
   157       reg_dat_o <= 0;
   158       mem_valid <= 0;
   159       started   <= 0;
   160       capturing <= 0;
   161    end
   163    // the host side control
   164    always @(posedge clk_i `CFG_RESET_SENSITIVITY)
   165      begin
   166 	if (rst_i == `TRUE) begin
   167 	   trig_type   <= 0;
   168 	   trace_stop  <= 0;
   169 	   trace_start <= 0;
   170 	   pc_low      <= 0;
   171 	   pc_high     <= 0;
   172 	   ack_o       <= 0;
   173 	end else begin
   174 	   if (stb_i == `TRUE && ack_o == `FALSE) begin
   175 	      if (rw_creg) begin // control register access
   176 		 ack_o <= `TRUE;		    
   177 		 if (we_i == `TRUE) begin
   178 		    case ({adr_i[11:2],2'b0})
   179 		      // write to trig type
   180 		      12'd0:
   181 			begin
   182 			   if (sel_i[0]) begin
   183 			      trig_type[4:0] <= dat_i[4:0];
   184                            end
   185                            if (sel_i[3]) begin
   186                               trace_start <= dat_i[31];
   187                               trace_stop  <= dat_i[30];
   188                            end
   189 			end
   190 		      12'd8:
   191 			begin
   192 			   if (sel_i[3]) pc_low[31:24] <= dat_i[31:24];
   193 			   if (sel_i[2]) pc_low[23:16] <= dat_i[23:16];
   194 			   if (sel_i[1]) pc_low[15:8]  <= dat_i[15:8];
   195 			   if (sel_i[0]) pc_low[7:0]   <= dat_i[7:0];			 
   196 			end
   197 		      12'd12:
   198 			begin
   199 			   if (sel_i[3]) pc_high[31:24] <= dat_i[31:24];
   200 			   if (sel_i[2]) pc_high[23:16] <= dat_i[23:16];
   201 			   if (sel_i[1]) pc_high[15:8]  <= dat_i[15:8];
   202 			   if (sel_i[0]) pc_high[7:0]   <= dat_i[7:0];			 
   203 			end
   204 		      12'd16:
   205                         begin
   206 			   if (sel_i[0])begin
   207                                stop_type[4:0] <= dat_i[4:0];
   208                            end
   209                         end
   210 		    endcase
   211 		 end else begin // read control registers
   212 		    case ({adr_i[11:2],2'b0})
   213 		      // read the trig type
   214 		      12'd0:
   215                         reg_dat_o <= {22'b1,capturing,mem_valid,ovrflw,trace_we,started,trig_type};
   216 		      12'd4:
   217                         reg_dat_o <= trace_len;			 
   218 		      12'd8:
   219 			reg_dat_o <= pc_low;
   220 		      12'd12:
   221 			reg_dat_o <= pc_high;		      
   222 		      default:
   223 			reg_dat_o <= {27'b0,stop_type};
   224 		    endcase
   225 		 end // else: !if(we_i == `TRUE)		 
   226 	      end else // read / write memory
   227 		if (we_i == `FALSE) begin
   228 		   ack_o <= `TRUE;
   229 		end else
   230 		  ack_o <= `FALSE;	      
   231 	      // not allowed to write to trace memory
   232 	   end else begin // if (stb_i == `TRUE)
   233 	      trace_start  <= `FALSE;
   234 	      trace_stop   <= `FALSE;
   235 	      ack_o        <= `FALSE;	      
   236 	   end // else: !if(stb_i == `TRUE)	   
   237 	end // else: !if(rst_i == `TRUE)
   238      end 
   240    wire [`LM32_WORD_RNG] trace_pc_tmp = {trace_pc,2'b0};
   242    // trace state machine
   243    reg [2:0] tstate;
   244    wire      pc_in_range = {trace_pc,2'b0} >= pc_low &&
   245 	                   {trace_pc,2'b0} <= pc_high;
   247    assign    trace_waddr = trace_len[mem_addr_width-1:0];
   249    wire trace_begin = ((trig_type[0] & trace_bret) ||
   250 		       (trig_type[1] & trace_eret) ||
   251 		       (trig_type[2] & pc_in_range & trace_pc_valid) ||
   252 		       (trig_type[3] & trace_exception & (trace_eid != `LM32_EID_BREAKPOINT)) ||
   253                        (trig_type[4] & trace_exception & (trace_eid == `LM32_EID_BREAKPOINT))
   254                       );
   257    wire trace_end = (trace_stop  ||
   258 		      (stop_type[0] & trace_bret) ||
   259 		      (stop_type[1] & trace_eret) ||
   260 		      (stop_type[2] & !pc_in_range & trace_pc_valid) ||
   261 		      (stop_type[3] & trace_exception & (trace_eid != `LM32_EID_BREAKPOINT)) ||
   262                       (stop_type[4] & trace_exception & (trace_eid == `LM32_EID_BREAKPOINT))
   263                     );
   265    assign trace_be = (trace_begin & (tstate == 3'd1));
   266    assign trace_last = (trace_stop & (tstate == 3'd2));
   268    always @(posedge clk_i `CFG_RESET_SENSITIVITY)
   269      begin
   270 	if (rst_i == `TRUE) begin
   271 	   tstate    <= 0;
   272 	   trace_we  <= 0;
   273 	   trace_len <= 0;	   
   274 	   ovrflw    <= `FALSE;
   275 	   mem_valid <= 0;
   276            started   <= 0;
   277            capturing <= 0;
   278 	end else begin
   279 	   case (tstate)
   280 	   3'd0:
   281 	     // start capture	     
   282 	     if (trace_start) begin
   283 		tstate <= 3'd1;
   284 		mem_valid <= 0;
   285                 started   <= 1;
   286 	     end
   287 	   3'd1:
   288 	     begin
   289 		// wait for trigger
   290 		if (trace_begin) begin
   291                    capturing <= 1;
   292 		   tstate    <= 3'd2;
   293 		   trace_we  <= `TRUE;
   294 		   trace_len <= 0;		
   295 		   ovrflw    <= `FALSE;			      
   296 		end
   297 	     end // case: 3'd1	     
   299 	   3'd2:
   300 	     begin
   301 		if (trace_pc_valid) begin
   302 		   if (trace_len[mem_addr_width])
   303 		     trace_len <= 0;
   304 		   else
   305 		     trace_len <= trace_len + 1;
   306 		end
   307 		if (!ovrflw) ovrflw <= trace_len[mem_addr_width];		
   308 		// wait for stop condition
   309 		if (trace_end) begin
   310 		   tstate    <= 3'd0;
   311 		   trace_we  <= 0;
   312 		   mem_valid <= 1;
   313                    started   <= 0;
   314                    capturing <= 0;
   315 		end
   316 	     end // case: 3'd2
   317 	   endcase
   318 	end // else: !if(rst_i == `TRUE)
   319      end
   320 endmodule
   321 `endif