Tue, 06 Apr 2010 18:27:55 +0100
Make cache 2-way associative
Switched from Direct Mapped to 2-Way Set Associative caches. Should boost speed
a bit.
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