lm32_trace.v

Mon, 05 Apr 2010 21:00:31 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Mon, 05 Apr 2010 21:00:31 +0100
changeset 6
a8e459b24c31
parent 0
cd0b58aa6f83
child 26
73de224304c1
permissions
-rw-r--r--

reduce size of caches to fit in DE1 FPGA

The default cache size makes the Icache and Dcache "just a bit" too big to
fit in the EP2C20 FPGA on the DE1 board. This commit reduces the Icache and
Dcache sizes to the defaults shown in the LatticeMico32 Processor Reference
Manual (pages 36 and 37).

     1 // =============================================================================
     2 //                           COPYRIGHT NOTICE
     3 // Copyright 2006 (c) Lattice Semiconductor Corporation
     4 // ALL RIGHTS RESERVED
     5 // This confidential and proprietary software may be used only as authorised by
     6 // a licensing agreement from Lattice Semiconductor Corporation.
     7 // The entire notice above must be reproduced on all authorized copies and
     8 // copies may only be made to the extent permitted by a licensing agreement from
     9 // Lattice Semiconductor Corporation.
    10 //
    11 // Lattice Semiconductor Corporation        TEL : 1-800-Lattice (USA and Canada)
    12 // 5555 NE Moore Court                            408-826-6000 (other locations)
    13 // Hillsboro, OR 97124                     web  : http://www.latticesemi.com/
    14 // U.S.A                                   email: techsupport@latticesemi.com
    15 // =============================================================================/
    16 //                         FILE DETAILS
    17 // Project          : LatticeMico32
    18 // File             : lm32_trace.v
    19 // Title            : PC Trace and associated logic.
    20 // Dependencies     : lm32_include.v, lm32_functions.v
    21 // Version          : 6.1.17
    22 //                  : Initial Release
    23 // Version          : 7.0SP2, 3.0
    24 //                  : No Change
    25 // Version          : 3.1
    26 //                  : No Change
    27 // =============================================================================
    29 `include "lm32_include.v"
    30 `include "system_conf.v"
    32 `ifdef CFG_TRACE_ENABLED
    33 module lm32_trace(
    34 		  // ----- Inputs -------
    35 		  clk_i,
    36 		  rst_i,
    37 		  stb_i,
    38 		  we_i,
    39 		  sel_i,
    40 		  dat_i,
    41 		  adr_i,
    43 		  trace_pc,
    44 		  trace_eid,
    45 		  trace_eret,
    46 		  trace_bret,
    47 		  trace_pc_valid,
    48 		  trace_exception,
    50 		  // -- outputs
    51 		  ack_o,
    52 		  dat_o);
    54    input clk_i;   
    55    input rst_i;   
    56    input stb_i;
    57    input we_i;   
    58    input [3:0] sel_i;
    59    input [`LM32_WORD_RNG] dat_i;
    60    input [`LM32_WORD_RNG] adr_i;
    61    input [`LM32_PC_RNG]   trace_pc;
    62    input [`LM32_EID_RNG]  trace_eid;
    63    input 		  trace_eret;
    64    input 		  trace_bret;
    65    input 		  trace_pc_valid;
    66    input 		  trace_exception;
    67    // -- outputs
    68    output 		  ack_o;
    69    output [`LM32_WORD_RNG] dat_o;
    70    reg 			   ovrflw;
    72    function integer clogb2;
    73       input [31:0] value;
    74       begin
    75 	 for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1)
    76            value = value >> 1;
    77       end
    78    endfunction 
    80   // instantiate the trace memory
    81   parameter mem_data_width = `LM32_PC_WIDTH;
    82   parameter mem_addr_width = clogb2(`CFG_TRACE_DEPTH-1);
    84    wire [`LM32_PC_RNG] 	     trace_dat_o;
    85    wire [mem_addr_width-1:0] trace_raddr;
    86    wire [mem_addr_width-1:0] trace_waddr;
    87    reg  		     trace_we;
    88    wire 		     trace_be, trace_last;   
    89    wire 		     rw_creg = adr_i[12]; 
    91    lm32_ram #(.data_width    (mem_data_width),
    92 	      .address_width (mem_addr_width)) 
    93      trace_mem (.read_clk  	(clk_i),
    94 		.write_clk 	(clk_i),
    95 		.reset     	(rst_i),
    96 		.read_address 	(adr_i[mem_addr_width+1:2]),
    97 		.write_address  (trace_waddr),
    98 		.enable_read 	(`TRUE),
    99 		.enable_write 	((trace_we | trace_be) & trace_pc_valid & !trace_last),
   100 		.write_enable 	(`TRUE),
   101 		.write_data   	(trace_pc),
   102 		.read_data    	(trace_dat_o));
   104    // trigger type & stop type
   105    //  trig_type [0] = start capture when bret
   106    //  trig_type [1] = start capture when eret
   107    //  trig_type [2] = start capture when PC within a range
   108    //  trig_type [3] = start when an exception happens (other than breakpoint)
   109    //  trig_type [4] = start when a breakpoint exception happens
   112    reg [4:0]	        trig_type;	   // at address  0
   113    reg [4:0] 	        stop_type;         // at address 16   
   114    reg [`LM32_WORD_RNG] trace_len;   	   // at address  4
   115    reg [`LM32_WORD_RNG]   pc_low;	   // at address  8
   116    reg [`LM32_WORD_RNG]   pc_high;	   // at address 12
   117    reg 		        trace_start,trace_stop;
   118    reg 		        ack_o;
   119    reg 			mem_valid;   
   120    reg [`LM32_WORD_RNG] reg_dat_o;
   121    reg started;
   122    reg capturing;
   123    assign 		dat_o = (rw_creg ? reg_dat_o : trace_dat_o);
   125    initial begin
   126       trig_type <= 0;
   127       stop_type <= 0;
   128       trace_len <= 0;
   129       pc_low    <= 0;
   130       pc_high   <= 0;
   131       trace_start <= 0;
   132       trace_stop  <= 0;
   133       ack_o 	<= 0;
   134       reg_dat_o <= 0;
   135       mem_valid <= 0;
   136       started   <= 0;
   137       capturing <= 0;
   138    end
   140    // the host side control
   141    always @(posedge clk_i `CFG_RESET_SENSITIVITY)
   142      begin
   143 	if (rst_i == `TRUE) begin
   144 	   trig_type   <= 0;
   145 	   trace_stop  <= 0;
   146 	   trace_start <= 0;
   147 	   pc_low      <= 0;
   148 	   pc_high     <= 0;
   149 	   ack_o       <= 0;
   150 	end else begin
   151 	   if (stb_i == `TRUE && ack_o == `FALSE) begin
   152 	      if (rw_creg) begin // control register access
   153 		 ack_o <= `TRUE;		    
   154 		 if (we_i == `TRUE) begin
   155 		    case ({adr_i[11:2],2'b0})
   156 		      // write to trig type
   157 		      12'd0:
   158 			begin
   159 			   if (sel_i[0]) begin
   160 			      trig_type[4:0] <= dat_i[4:0];
   161                            end
   162                            if (sel_i[3]) begin
   163                               trace_start <= dat_i[31];
   164                               trace_stop  <= dat_i[30];
   165                            end
   166 			end
   167 		      12'd8:
   168 			begin
   169 			   if (sel_i[3]) pc_low[31:24] <= dat_i[31:24];
   170 			   if (sel_i[2]) pc_low[23:16] <= dat_i[23:16];
   171 			   if (sel_i[1]) pc_low[15:8]  <= dat_i[15:8];
   172 			   if (sel_i[0]) pc_low[7:0]   <= dat_i[7:0];			 
   173 			end
   174 		      12'd12:
   175 			begin
   176 			   if (sel_i[3]) pc_high[31:24] <= dat_i[31:24];
   177 			   if (sel_i[2]) pc_high[23:16] <= dat_i[23:16];
   178 			   if (sel_i[1]) pc_high[15:8]  <= dat_i[15:8];
   179 			   if (sel_i[0]) pc_high[7:0]   <= dat_i[7:0];			 
   180 			end
   181 		      12'd16:
   182                         begin
   183 			   if (sel_i[0])begin
   184                                stop_type[4:0] <= dat_i[4:0];
   185                            end
   186                         end
   187 		    endcase
   188 		 end else begin // read control registers
   189 		    case ({adr_i[11:2],2'b0})
   190 		      // read the trig type
   191 		      12'd0:
   192                         reg_dat_o <= {22'b1,capturing,mem_valid,ovrflw,trace_we,started,trig_type};
   193 		      12'd4:
   194                         reg_dat_o <= trace_len;			 
   195 		      12'd8:
   196 			reg_dat_o <= pc_low;
   197 		      12'd12:
   198 			reg_dat_o <= pc_high;		      
   199 		      default:
   200 			reg_dat_o <= {27'b0,stop_type};
   201 		    endcase
   202 		 end // else: !if(we_i == `TRUE)		 
   203 	      end else // read / write memory
   204 		if (we_i == `FALSE) begin
   205 		   ack_o <= `TRUE;
   206 		end else
   207 		  ack_o <= `FALSE;	      
   208 	      // not allowed to write to trace memory
   209 	   end else begin // if (stb_i == `TRUE)
   210 	      trace_start  <= `FALSE;
   211 	      trace_stop   <= `FALSE;
   212 	      ack_o        <= `FALSE;	      
   213 	   end // else: !if(stb_i == `TRUE)	   
   214 	end // else: !if(rst_i == `TRUE)
   215      end 
   217    wire [`LM32_WORD_RNG] trace_pc_tmp = {trace_pc,2'b0};
   219    // trace state machine
   220    reg [2:0] tstate;
   221    wire      pc_in_range = {trace_pc,2'b0} >= pc_low &&
   222 	                   {trace_pc,2'b0} <= pc_high;
   224    assign    trace_waddr = trace_len[mem_addr_width-1:0];
   226    wire trace_begin = ((trig_type[0] & trace_bret) ||
   227 		       (trig_type[1] & trace_eret) ||
   228 		       (trig_type[2] & pc_in_range & trace_pc_valid) ||
   229 		       (trig_type[3] & trace_exception & (trace_eid != `LM32_EID_BREAKPOINT)) ||
   230                        (trig_type[4] & trace_exception & (trace_eid == `LM32_EID_BREAKPOINT))
   231                       );
   234    wire trace_end = (trace_stop  ||
   235 		      (stop_type[0] & trace_bret) ||
   236 		      (stop_type[1] & trace_eret) ||
   237 		      (stop_type[2] & !pc_in_range & trace_pc_valid) ||
   238 		      (stop_type[3] & trace_exception & (trace_eid != `LM32_EID_BREAKPOINT)) ||
   239                       (stop_type[4] & trace_exception & (trace_eid == `LM32_EID_BREAKPOINT))
   240                     );
   242    assign trace_be = (trace_begin & (tstate == 3'd1));
   243    assign trace_last = (trace_stop & (tstate == 3'd2));
   245    always @(posedge clk_i `CFG_RESET_SENSITIVITY)
   246      begin
   247 	if (rst_i == `TRUE) begin
   248 	   tstate    <= 0;
   249 	   trace_we  <= 0;
   250 	   trace_len <= 0;	   
   251 	   ovrflw    <= `FALSE;
   252 	   mem_valid <= 0;
   253            started   <= 0;
   254            capturing <= 0;
   255 	end else begin
   256 	   case (tstate)
   257 	   3'd0:
   258 	     // start capture	     
   259 	     if (trace_start) begin
   260 		tstate <= 3'd1;
   261 		mem_valid <= 0;
   262                 started   <= 1;
   263 	     end
   264 	   3'd1:
   265 	     begin
   266 		// wait for trigger
   267 		if (trace_begin) begin
   268                    capturing <= 1;
   269 		   tstate    <= 3'd2;
   270 		   trace_we  <= `TRUE;
   271 		   trace_len <= 0;		
   272 		   ovrflw    <= `FALSE;			      
   273 		end
   274 	     end // case: 3'd1	     
   276 	   3'd2:
   277 	     begin
   278 		if (trace_pc_valid) begin
   279 		   if (trace_len[mem_addr_width])
   280 		     trace_len <= 0;
   281 		   else
   282 		     trace_len <= trace_len + 1;
   283 		end
   284 		if (!ovrflw) ovrflw <= trace_len[mem_addr_width];		
   285 		// wait for stop condition
   286 		if (trace_end) begin
   287 		   tstate    <= 3'd0;
   288 		   trace_we  <= 0;
   289 		   mem_valid <= 1;
   290                    started   <= 0;
   291                    capturing <= 0;
   292 		end
   293 	     end // case: 3'd2
   294 	   endcase
   295 	end // else: !if(rst_i == `TRUE)
   296      end
   297 endmodule
   298 `endif