Sat, 06 Aug 2011 00:02:46 +0100
[UPSTREAM PULL] Update baseline to LatticeMico32 v3.8 from Diamond 1.3-lm32 distribution package (datestamp May 2011)
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 <= #1 0;
150 stop_type <= #1 0;
151 trace_len <= #1 0;
152 pc_low <= #1 0;
153 pc_high <= #1 0;
154 trace_start <= #1 0;
155 trace_stop <= #1 0;
156 ack_o <= #1 0;
157 reg_dat_o <= #1 0;
158 mem_valid <= #1 0;
159 started <= #1 0;
160 capturing <= #1 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 <= #1 0;
168 trace_stop <= #1 0;
169 trace_start <= #1 0;
170 pc_low <= #1 0;
171 pc_high <= #1 0;
172 ack_o <= #1 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 <= #1 `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] <= #1 dat_i[4:0];
184 end
185 if (sel_i[3]) begin
186 trace_start <= #1 dat_i[31];
187 trace_stop <= #1 dat_i[30];
188 end
189 end
190 12'd8:
191 begin
192 if (sel_i[3]) pc_low[31:24] <= #1 dat_i[31:24];
193 if (sel_i[2]) pc_low[23:16] <= #1 dat_i[23:16];
194 if (sel_i[1]) pc_low[15:8] <= #1 dat_i[15:8];
195 if (sel_i[0]) pc_low[7:0] <= #1 dat_i[7:0];
196 end
197 12'd12:
198 begin
199 if (sel_i[3]) pc_high[31:24] <= #1 dat_i[31:24];
200 if (sel_i[2]) pc_high[23:16] <= #1 dat_i[23:16];
201 if (sel_i[1]) pc_high[15:8] <= #1 dat_i[15:8];
202 if (sel_i[0]) pc_high[7:0] <= #1 dat_i[7:0];
203 end
204 12'd16:
205 begin
206 if (sel_i[0])begin
207 stop_type[4:0] <= #1 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 <= #1 {22'b1,capturing,mem_valid,ovrflw,trace_we,started,trig_type};
216 12'd4:
217 reg_dat_o <= #1 trace_len;
218 12'd8:
219 reg_dat_o <= #1 pc_low;
220 12'd12:
221 reg_dat_o <= #1 pc_high;
222 default:
223 reg_dat_o <= #1 {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 <= #1 `TRUE;
229 end else
230 ack_o <= #1 `FALSE;
231 // not allowed to write to trace memory
232 end else begin // if (stb_i == `TRUE)
233 trace_start <= #1 `FALSE;
234 trace_stop <= #1 `FALSE;
235 ack_o <= #1 `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 <= #1 0;
272 trace_we <= #1 0;
273 trace_len <= #1 0;
274 ovrflw <= #1 `FALSE;
275 mem_valid <= #1 0;
276 started <= #1 0;
277 capturing <= #1 0;
278 end else begin
279 case (tstate)
280 3'd0:
281 // start capture
282 if (trace_start) begin
283 tstate <= #1 3'd1;
284 mem_valid <= #1 0;
285 started <= #1 1;
286 end
287 3'd1:
288 begin
289 // wait for trigger
290 if (trace_begin) begin
291 capturing <= #1 1;
292 tstate <= #1 3'd2;
293 trace_we <= #1 `TRUE;
294 trace_len <= #1 0;
295 ovrflw <= #1 `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 <= #1 0;
304 else
305 trace_len <= #1 trace_len + 1;
306 end
307 if (!ovrflw) ovrflw <= #1 trace_len[mem_addr_width];
308 // wait for stop condition
309 if (trace_end) begin
310 tstate <= #1 3'd0;
311 trace_we <= #1 0;
312 mem_valid <= #1 1;
313 started <= #1 0;
314 capturing <= #1 0;
315 end
316 end // case: 3'd2
317 endcase
318 end // else: !if(rst_i == `TRUE)
319 end
320 endmodule
321 `endif