Mon, 05 Apr 2010 21:00:31 +0100
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