lm32_debug.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

philpem@26 1 // ==================================================================
philpem@26 2 // >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
philpem@26 3 // ------------------------------------------------------------------
philpem@26 4 // Copyright (c) 2006-2011 by Lattice Semiconductor Corporation
philpem@26 5 // ALL RIGHTS RESERVED
philpem@26 6 // ------------------------------------------------------------------
philpem@26 7 //
philpem@26 8 // IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM.
philpem@26 9 //
philpem@26 10 // Permission:
philpem@26 11 //
philpem@26 12 // Lattice Semiconductor grants permission to use this code
philpem@26 13 // pursuant to the terms of the Lattice Semiconductor Corporation
philpem@26 14 // Open Source License Agreement.
philpem@26 15 //
philpem@26 16 // Disclaimer:
philpem@0 17 //
philpem@26 18 // Lattice Semiconductor provides no warranty regarding the use or
philpem@26 19 // functionality of this code. It is the user's responsibility to
philpem@26 20 // verify the userís design for consistency and functionality through
philpem@26 21 // the use of formal verification methods.
philpem@26 22 //
philpem@26 23 // --------------------------------------------------------------------
philpem@26 24 //
philpem@26 25 // Lattice Semiconductor Corporation
philpem@26 26 // 5555 NE Moore Court
philpem@26 27 // Hillsboro, OR 97214
philpem@26 28 // U.S.A
philpem@26 29 //
philpem@26 30 // TEL: 1-800-Lattice (USA and Canada)
philpem@26 31 // 503-286-8001 (other locations)
philpem@26 32 //
philpem@26 33 // web: http://www.latticesemi.com/
philpem@26 34 // email: techsupport@latticesemi.com
philpem@26 35 //
philpem@26 36 // --------------------------------------------------------------------
philpem@0 37 // FILE DETAILS
philpem@0 38 // Project : LatticeMico32
philpem@0 39 // File : lm32_debug.v
philpem@0 40 // Title : Hardware debug registers and associated logic.
philpem@0 41 // Dependencies : lm32_include.v
philpem@0 42 // Version : 6.1.17
philpem@0 43 // : Initial Release
philpem@0 44 // Version : 7.0SP2, 3.0
philpem@0 45 // : No Change
philpem@0 46 // Version : 3.1
philpem@0 47 // : No Change
philpem@0 48 // Version : 3.2
philpem@0 49 // : Fixed simulation bug which flares up when number of
philpem@0 50 // : watchpoints is zero.
philpem@0 51 // =============================================================================
philpem@0 52
philpem@0 53 `include "lm32_include.v"
philpem@0 54
philpem@0 55 `ifdef CFG_DEBUG_ENABLED
philpem@0 56
philpem@0 57 // States for single-step FSM
philpem@0 58 `define LM32_DEBUG_SS_STATE_RNG 2:0
philpem@0 59 `define LM32_DEBUG_SS_STATE_IDLE 3'b000
philpem@0 60 `define LM32_DEBUG_SS_STATE_WAIT_FOR_RET 3'b001
philpem@0 61 `define LM32_DEBUG_SS_STATE_EXECUTE_ONE_INSN 3'b010
philpem@0 62 `define LM32_DEBUG_SS_STATE_RAISE_BREAKPOINT 3'b011
philpem@0 63 `define LM32_DEBUG_SS_STATE_RESTART 3'b100
philpem@0 64
philpem@0 65 /////////////////////////////////////////////////////
philpem@0 66 // Module interface
philpem@0 67 /////////////////////////////////////////////////////
philpem@0 68
philpem@0 69 module lm32_debug (
philpem@0 70 // ----- Inputs -------
philpem@0 71 clk_i,
philpem@0 72 rst_i,
philpem@0 73 pc_x,
philpem@0 74 load_x,
philpem@0 75 store_x,
philpem@0 76 load_store_address_x,
philpem@0 77 csr_write_enable_x,
philpem@0 78 csr_write_data,
philpem@0 79 csr_x,
philpem@0 80 `ifdef CFG_HW_DEBUG_ENABLED
philpem@0 81 jtag_csr_write_enable,
philpem@0 82 jtag_csr_write_data,
philpem@0 83 jtag_csr,
philpem@0 84 `endif
philpem@0 85 `ifdef LM32_SINGLE_STEP_ENABLED
philpem@0 86 eret_q_x,
philpem@0 87 bret_q_x,
philpem@0 88 stall_x,
philpem@0 89 exception_x,
philpem@0 90 q_x,
philpem@0 91 `ifdef CFG_DCACHE_ENABLED
philpem@0 92 dcache_refill_request,
philpem@0 93 `endif
philpem@0 94 `endif
philpem@0 95 // ----- Outputs -------
philpem@0 96 `ifdef LM32_SINGLE_STEP_ENABLED
philpem@0 97 dc_ss,
philpem@0 98 `endif
philpem@0 99 dc_re,
philpem@0 100 bp_match,
philpem@0 101 wp_match
philpem@0 102 );
philpem@0 103
philpem@0 104 /////////////////////////////////////////////////////
philpem@0 105 // Parameters
philpem@0 106 /////////////////////////////////////////////////////
philpem@0 107
philpem@0 108 parameter breakpoints = 0; // Number of breakpoint CSRs
philpem@0 109 parameter watchpoints = 0; // Number of watchpoint CSRs
philpem@0 110
philpem@0 111 /////////////////////////////////////////////////////
philpem@0 112 // Inputs
philpem@0 113 /////////////////////////////////////////////////////
philpem@0 114
philpem@0 115 input clk_i; // Clock
philpem@0 116 input rst_i; // Reset
philpem@0 117
philpem@0 118 input [`LM32_PC_RNG] pc_x; // X stage PC
philpem@0 119 input load_x; // Load instruction in X stage
philpem@0 120 input store_x; // Store instruction in X stage
philpem@0 121 input [`LM32_WORD_RNG] load_store_address_x; // Load or store effective address
philpem@0 122 input csr_write_enable_x; // wcsr instruction in X stage
philpem@0 123 input [`LM32_WORD_RNG] csr_write_data; // Data to write to CSR
philpem@0 124 input [`LM32_CSR_RNG] csr_x; // Which CSR to write
philpem@0 125 `ifdef CFG_HW_DEBUG_ENABLED
philpem@0 126 input jtag_csr_write_enable; // JTAG interface CSR write enable
philpem@0 127 input [`LM32_WORD_RNG] jtag_csr_write_data; // Data to write to CSR
philpem@0 128 input [`LM32_CSR_RNG] jtag_csr; // Which CSR to write
philpem@0 129 `endif
philpem@0 130 `ifdef LM32_SINGLE_STEP_ENABLED
philpem@0 131 input eret_q_x; // eret instruction in X stage
philpem@0 132 input bret_q_x; // bret instruction in X stage
philpem@0 133 input stall_x; // Instruction in X stage is stalled
philpem@0 134 input exception_x; // An exception has occured in X stage
philpem@0 135 input q_x; // Indicates the instruction in the X stage is qualified
philpem@0 136 `ifdef CFG_DCACHE_ENABLED
philpem@0 137 input dcache_refill_request; // Indicates data cache wants to be refilled
philpem@0 138 `endif
philpem@0 139 `endif
philpem@0 140
philpem@0 141 /////////////////////////////////////////////////////
philpem@0 142 // Outputs
philpem@0 143 /////////////////////////////////////////////////////
philpem@0 144
philpem@0 145 `ifdef LM32_SINGLE_STEP_ENABLED
philpem@0 146 output dc_ss; // Single-step enable
philpem@0 147 reg dc_ss;
philpem@0 148 `endif
philpem@0 149 output dc_re; // Remap exceptions
philpem@0 150 reg dc_re;
philpem@0 151 output bp_match; // Indicates a breakpoint has matched
philpem@0 152 wire bp_match;
philpem@0 153 output wp_match; // Indicates a watchpoint has matched
philpem@0 154 wire wp_match;
philpem@0 155
philpem@0 156 /////////////////////////////////////////////////////
philpem@0 157 // Internal nets and registers
philpem@0 158 /////////////////////////////////////////////////////
philpem@0 159
philpem@0 160 genvar i; // Loop index for generate statements
philpem@0 161
philpem@0 162 // Debug CSRs
philpem@0 163
philpem@0 164 reg [`LM32_PC_RNG] bp_a[0:breakpoints-1]; // Instruction breakpoint address
philpem@0 165 reg bp_e[0:breakpoints-1]; // Instruction breakpoint enable
philpem@0 166 wire [0:breakpoints-1]bp_match_n; // Indicates if a h/w instruction breakpoint matched
philpem@0 167
philpem@0 168 reg [`LM32_WPC_C_RNG] wpc_c[0:watchpoints-1]; // Watchpoint enable
philpem@0 169 reg [`LM32_WORD_RNG] wp[0:watchpoints-1]; // Watchpoint address
philpem@0 170 wire [0:watchpoints]wp_match_n; // Indicates if a h/w data watchpoint matched
philpem@0 171
philpem@0 172 wire debug_csr_write_enable; // Debug CSR write enable (from either a wcsr instruction of external debugger)
philpem@0 173 wire [`LM32_WORD_RNG] debug_csr_write_data; // Data to write to debug CSR
philpem@0 174 wire [`LM32_CSR_RNG] debug_csr; // Debug CSR to write to
philpem@0 175
philpem@0 176 `ifdef LM32_SINGLE_STEP_ENABLED
philpem@0 177 // FIXME: Declaring this as a reg causes ModelSim 6.1.15b to crash, so use integer for now
philpem@0 178 //reg [`LM32_DEBUG_SS_STATE_RNG] state; // State of single-step FSM
philpem@0 179 integer state; // State of single-step FSM
philpem@0 180 `endif
philpem@0 181
philpem@0 182 /////////////////////////////////////////////////////
philpem@0 183 // Functions
philpem@0 184 /////////////////////////////////////////////////////
philpem@0 185
philpem@0 186 `include "lm32_functions.v"
philpem@0 187
philpem@0 188 /////////////////////////////////////////////////////
philpem@0 189 // Combinational Logic
philpem@0 190 /////////////////////////////////////////////////////
philpem@0 191
philpem@0 192 // Check for breakpoints
philpem@0 193 generate
philpem@0 194 for (i = 0; i < breakpoints; i = i + 1)
philpem@0 195 begin : bp_comb
philpem@0 196 assign bp_match_n[i] = ((bp_a[i] == pc_x) && (bp_e[i] == `TRUE));
philpem@0 197 end
philpem@0 198 endgenerate
philpem@0 199 generate
philpem@0 200 `ifdef LM32_SINGLE_STEP_ENABLED
philpem@0 201 if (breakpoints > 0)
philpem@0 202 assign bp_match = (|bp_match_n) || (state == `LM32_DEBUG_SS_STATE_RAISE_BREAKPOINT);
philpem@0 203 else
philpem@0 204 assign bp_match = state == `LM32_DEBUG_SS_STATE_RAISE_BREAKPOINT;
philpem@0 205 `else
philpem@0 206 if (breakpoints > 0)
philpem@0 207 assign bp_match = |bp_match_n;
philpem@0 208 else
philpem@0 209 assign bp_match = `FALSE;
philpem@0 210 `endif
philpem@0 211 endgenerate
philpem@0 212
philpem@0 213 // Check for watchpoints
philpem@0 214 generate
philpem@0 215 for (i = 0; i < watchpoints; i = i + 1)
philpem@0 216 begin : wp_comb
philpem@0 217 assign wp_match_n[i] = (wp[i] == load_store_address_x) && ((load_x & wpc_c[i][0]) | (store_x & wpc_c[i][1]));
philpem@0 218 end
philpem@0 219 endgenerate
philpem@0 220 generate
philpem@0 221 if (watchpoints > 0)
philpem@0 222 assign wp_match = |wp_match_n;
philpem@0 223 else
philpem@0 224 assign wp_match = `FALSE;
philpem@0 225 endgenerate
philpem@0 226
philpem@0 227 `ifdef CFG_HW_DEBUG_ENABLED
philpem@0 228 // Multiplex between wcsr instruction writes and debugger writes to the debug CSRs
philpem@0 229 assign debug_csr_write_enable = (csr_write_enable_x == `TRUE) || (jtag_csr_write_enable == `TRUE);
philpem@0 230 assign debug_csr_write_data = jtag_csr_write_enable == `TRUE ? jtag_csr_write_data : csr_write_data;
philpem@0 231 assign debug_csr = jtag_csr_write_enable == `TRUE ? jtag_csr : csr_x;
philpem@0 232 `else
philpem@0 233 assign debug_csr_write_enable = csr_write_enable_x;
philpem@0 234 assign debug_csr_write_data = csr_write_data;
philpem@0 235 assign debug_csr = csr_x;
philpem@0 236 `endif
philpem@0 237
philpem@0 238 /////////////////////////////////////////////////////
philpem@0 239 // Sequential Logic
philpem@0 240 /////////////////////////////////////////////////////
philpem@0 241
philpem@0 242 // Breakpoint address and enable CSRs
philpem@0 243 generate
philpem@0 244 for (i = 0; i < breakpoints; i = i + 1)
philpem@0 245 begin : bp_seq
philpem@0 246 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
philpem@0 247 begin
philpem@0 248 if (rst_i == `TRUE)
philpem@0 249 begin
philpem@27 250 bp_a[i] <= {`LM32_PC_WIDTH{1'bx}};
philpem@27 251 bp_e[i] <= `FALSE;
philpem@0 252 end
philpem@0 253 else
philpem@0 254 begin
philpem@0 255 if ((debug_csr_write_enable == `TRUE) && (debug_csr == `LM32_CSR_BP0 + i))
philpem@0 256 begin
philpem@27 257 bp_a[i] <= debug_csr_write_data[`LM32_PC_RNG];
philpem@27 258 bp_e[i] <= debug_csr_write_data[0];
philpem@0 259 end
philpem@0 260 end
philpem@0 261 end
philpem@0 262 end
philpem@0 263 endgenerate
philpem@0 264
philpem@0 265 // Watchpoint address and control flags CSRs
philpem@0 266 generate
philpem@0 267 for (i = 0; i < watchpoints; i = i + 1)
philpem@0 268 begin : wp_seq
philpem@0 269 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
philpem@0 270 begin
philpem@0 271 if (rst_i == `TRUE)
philpem@0 272 begin
philpem@27 273 wp[i] <= {`LM32_WORD_WIDTH{1'bx}};
philpem@27 274 wpc_c[i] <= `LM32_WPC_C_DISABLED;
philpem@0 275 end
philpem@0 276 else
philpem@0 277 begin
philpem@0 278 if (debug_csr_write_enable == `TRUE)
philpem@0 279 begin
philpem@0 280 if (debug_csr == `LM32_CSR_DC)
philpem@27 281 wpc_c[i] <= debug_csr_write_data[3+i*2:2+i*2];
philpem@0 282 if (debug_csr == `LM32_CSR_WP0 + i)
philpem@27 283 wp[i] <= debug_csr_write_data;
philpem@0 284 end
philpem@0 285 end
philpem@0 286 end
philpem@0 287 end
philpem@0 288 endgenerate
philpem@0 289
philpem@0 290 // Remap exceptions control bit
philpem@0 291 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
philpem@0 292 begin
philpem@0 293 if (rst_i == `TRUE)
philpem@27 294 dc_re <= `FALSE;
philpem@0 295 else
philpem@0 296 begin
philpem@0 297 if ((debug_csr_write_enable == `TRUE) && (debug_csr == `LM32_CSR_DC))
philpem@27 298 dc_re <= debug_csr_write_data[1];
philpem@0 299 end
philpem@0 300 end
philpem@0 301
philpem@0 302 `ifdef LM32_SINGLE_STEP_ENABLED
philpem@0 303 // Single-step control flag
philpem@0 304 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
philpem@0 305 begin
philpem@0 306 if (rst_i == `TRUE)
philpem@0 307 begin
philpem@27 308 state <= `LM32_DEBUG_SS_STATE_IDLE;
philpem@27 309 dc_ss <= `FALSE;
philpem@0 310 end
philpem@0 311 else
philpem@0 312 begin
philpem@0 313 if ((debug_csr_write_enable == `TRUE) && (debug_csr == `LM32_CSR_DC))
philpem@0 314 begin
philpem@27 315 dc_ss <= debug_csr_write_data[0];
philpem@0 316 if (debug_csr_write_data[0] == `FALSE)
philpem@27 317 state <= `LM32_DEBUG_SS_STATE_IDLE;
philpem@0 318 else
philpem@27 319 state <= `LM32_DEBUG_SS_STATE_WAIT_FOR_RET;
philpem@0 320 end
philpem@0 321 case (state)
philpem@0 322 `LM32_DEBUG_SS_STATE_WAIT_FOR_RET:
philpem@0 323 begin
philpem@0 324 // Wait for eret or bret instruction to be executed
philpem@0 325 if ( ( (eret_q_x == `TRUE)
philpem@0 326 || (bret_q_x == `TRUE)
philpem@0 327 )
philpem@0 328 && (stall_x == `FALSE)
philpem@0 329 )
philpem@27 330 state <= `LM32_DEBUG_SS_STATE_EXECUTE_ONE_INSN;
philpem@0 331 end
philpem@0 332 `LM32_DEBUG_SS_STATE_EXECUTE_ONE_INSN:
philpem@0 333 begin
philpem@0 334 // Wait for an instruction to be executed
philpem@0 335 if ((q_x == `TRUE) && (stall_x == `FALSE))
philpem@27 336 state <= `LM32_DEBUG_SS_STATE_RAISE_BREAKPOINT;
philpem@0 337 end
philpem@0 338 `LM32_DEBUG_SS_STATE_RAISE_BREAKPOINT:
philpem@0 339 begin
philpem@0 340 // Wait for exception to be raised
philpem@0 341 `ifdef CFG_DCACHE_ENABLED
philpem@0 342 if (dcache_refill_request == `TRUE)
philpem@27 343 state <= `LM32_DEBUG_SS_STATE_EXECUTE_ONE_INSN;
philpem@0 344 else
philpem@0 345 `endif
philpem@0 346 if ((exception_x == `TRUE) && (q_x == `TRUE) && (stall_x == `FALSE))
philpem@0 347 begin
philpem@27 348 dc_ss <= `FALSE;
philpem@27 349 state <= `LM32_DEBUG_SS_STATE_RESTART;
philpem@0 350 end
philpem@0 351 end
philpem@0 352 `LM32_DEBUG_SS_STATE_RESTART:
philpem@0 353 begin
philpem@0 354 // Watch to see if stepped instruction is restarted due to a cache miss
philpem@0 355 `ifdef CFG_DCACHE_ENABLED
philpem@0 356 if (dcache_refill_request == `TRUE)
philpem@27 357 state <= `LM32_DEBUG_SS_STATE_EXECUTE_ONE_INSN;
philpem@0 358 else
philpem@0 359 `endif
philpem@27 360 state <= `LM32_DEBUG_SS_STATE_IDLE;
philpem@0 361 end
philpem@0 362 endcase
philpem@0 363 end
philpem@0 364 end
philpem@0 365 `endif
philpem@0 366
philpem@0 367 endmodule
philpem@0 368
philpem@0 369 `endif