lm32_instruction_unit.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_instruction_unit.v
philpem@0 40 // Title : Instruction unit
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 // : Support for static branch prediction is added. Fetching of
philpem@0 48 // : instructions can also be altered by branches predicted in D
philpem@0 49 // : stage of pipeline, and mispredicted branches in the X and M
philpem@0 50 // : stages of the pipeline.
philpem@0 51 // Version : 3.2
philpem@0 52 // : EBRs use SYNC resets instead of ASYNC resets.
philpem@0 53 // Version : 3.3
philpem@0 54 // : Support for a non-cacheable Instruction Memory that has a
philpem@0 55 // : single-cycle access latency. This memory can be accessed by
philpem@0 56 // : data port of LM32 (so that debugger has access to it).
philpem@0 57 // Version : 3.4
philpem@0 58 // : No change
philpem@0 59 // Version : 3.5
philpem@0 60 // : Bug fix: Inline memory is correctly generated if it is not a
philpem@0 61 // : power-of-two.
philpem@0 62 // : Bug fix: Fixed a bug that caused LM32 (configured without
philpem@0 63 // : instruction cache) to lock up in to an infinite loop due to a
philpem@0 64 // : instruction bus error when EBA was set to instruction inline
philpem@0 65 // : memory.
philpem@26 66 // Version : 3.8
philpem@26 67 // : Feature: Support for dynamically switching EBA to DEBA via a
philpem@26 68 // : GPIO.
philpem@0 69 // =============================================================================
philpem@0 70
philpem@0 71 `include "lm32_include.v"
philpem@0 72
philpem@0 73 /////////////////////////////////////////////////////
philpem@0 74 // Module interface
philpem@0 75 /////////////////////////////////////////////////////
philpem@0 76
philpem@0 77 module lm32_instruction_unit (
philpem@0 78 // ----- Inputs -------
philpem@0 79 clk_i,
philpem@0 80 rst_i,
philpem@26 81 `ifdef CFG_DEBUG_ENABLED
philpem@26 82 `ifdef CFG_ALTERNATE_EBA
philpem@26 83 at_debug,
philpem@26 84 `endif
philpem@26 85 `endif
philpem@0 86 // From pipeline
philpem@0 87 stall_a,
philpem@0 88 stall_f,
philpem@0 89 stall_d,
philpem@0 90 stall_x,
philpem@0 91 stall_m,
philpem@0 92 valid_f,
philpem@0 93 valid_d,
philpem@0 94 kill_f,
philpem@0 95 branch_predict_taken_d,
philpem@0 96 branch_predict_address_d,
philpem@0 97 `ifdef CFG_FAST_UNCONDITIONAL_BRANCH
philpem@0 98 branch_taken_x,
philpem@0 99 branch_target_x,
philpem@0 100 `endif
philpem@0 101 exception_m,
philpem@0 102 branch_taken_m,
philpem@0 103 branch_mispredict_taken_m,
philpem@0 104 branch_target_m,
philpem@0 105 `ifdef CFG_ICACHE_ENABLED
philpem@0 106 iflush,
philpem@0 107 `endif
philpem@0 108 `ifdef CFG_DCACHE_ENABLED
philpem@0 109 dcache_restart_request,
philpem@0 110 dcache_refill_request,
philpem@0 111 dcache_refilling,
philpem@0 112 `endif
philpem@0 113 `ifdef CFG_IROM_ENABLED
philpem@0 114 irom_store_data_m,
philpem@0 115 irom_address_xm,
philpem@0 116 irom_we_xm,
philpem@0 117 `endif
philpem@0 118 `ifdef CFG_IWB_ENABLED
philpem@0 119 // From Wishbone
philpem@0 120 i_dat_i,
philpem@0 121 i_ack_i,
philpem@0 122 i_err_i,
philpem@0 123 `endif
philpem@0 124 `ifdef CFG_HW_DEBUG_ENABLED
philpem@0 125 jtag_read_enable,
philpem@0 126 jtag_write_enable,
philpem@0 127 jtag_write_data,
philpem@0 128 jtag_address,
philpem@0 129 `endif
philpem@0 130 // ----- Outputs -------
philpem@0 131 // To pipeline
philpem@0 132 pc_f,
philpem@0 133 pc_d,
philpem@0 134 pc_x,
philpem@0 135 pc_m,
philpem@0 136 pc_w,
philpem@0 137 `ifdef CFG_ICACHE_ENABLED
philpem@0 138 icache_stall_request,
philpem@0 139 icache_restart_request,
philpem@0 140 icache_refill_request,
philpem@0 141 icache_refilling,
philpem@0 142 `endif
philpem@0 143 `ifdef CFG_IROM_ENABLED
philpem@0 144 irom_data_m,
philpem@0 145 `endif
philpem@0 146 `ifdef CFG_IWB_ENABLED
philpem@0 147 // To Wishbone
philpem@0 148 i_dat_o,
philpem@0 149 i_adr_o,
philpem@0 150 i_cyc_o,
philpem@0 151 i_sel_o,
philpem@0 152 i_stb_o,
philpem@0 153 i_we_o,
philpem@0 154 i_cti_o,
philpem@0 155 i_lock_o,
philpem@0 156 i_bte_o,
philpem@0 157 `endif
philpem@0 158 `ifdef CFG_HW_DEBUG_ENABLED
philpem@0 159 jtag_read_data,
philpem@0 160 jtag_access_complete,
philpem@0 161 `endif
philpem@0 162 `ifdef CFG_BUS_ERRORS_ENABLED
philpem@0 163 bus_error_d,
philpem@0 164 `endif
philpem@0 165 `ifdef CFG_EBR_POSEDGE_REGISTER_FILE
philpem@0 166 instruction_f,
philpem@0 167 `endif
philpem@0 168 instruction_d
philpem@0 169 );
philpem@0 170
philpem@0 171 /////////////////////////////////////////////////////
philpem@0 172 // Parameters
philpem@0 173 /////////////////////////////////////////////////////
philpem@0 174
philpem@0 175 parameter associativity = 1; // Associativity of the cache (Number of ways)
philpem@0 176 parameter sets = 512; // Number of sets
philpem@0 177 parameter bytes_per_line = 16; // Number of bytes per cache line
philpem@0 178 parameter base_address = 0; // Base address of cachable memory
philpem@0 179 parameter limit = 0; // Limit (highest address) of cachable memory
philpem@0 180
philpem@0 181 // For bytes_per_line == 4, we set 1 so part-select range isn't reversed, even though not really used
philpem@0 182 localparam addr_offset_width = bytes_per_line == 4 ? 1 : clogb2(bytes_per_line)-1-2;
philpem@0 183 localparam addr_offset_lsb = 2;
philpem@0 184 localparam addr_offset_msb = (addr_offset_lsb+addr_offset_width-1);
philpem@0 185
philpem@0 186 /////////////////////////////////////////////////////
philpem@0 187 // Inputs
philpem@0 188 /////////////////////////////////////////////////////
philpem@0 189
philpem@0 190 input clk_i; // Clock
philpem@0 191 input rst_i; // Reset
philpem@0 192
philpem@26 193 `ifdef CFG_DEBUG_ENABLED
philpem@26 194 `ifdef CFG_ALTERNATE_EBA
philpem@26 195 input at_debug; // GPIO input that maps EBA to DEBA
philpem@26 196 `endif
philpem@26 197 `endif
philpem@26 198
philpem@0 199 input stall_a; // Stall A stage instruction
philpem@0 200 input stall_f; // Stall F stage instruction
philpem@0 201 input stall_d; // Stall D stage instruction
philpem@0 202 input stall_x; // Stall X stage instruction
philpem@0 203 input stall_m; // Stall M stage instruction
philpem@0 204 input valid_f; // Instruction in F stage is valid
philpem@0 205 input valid_d; // Instruction in D stage is valid
philpem@0 206 input kill_f; // Kill instruction in F stage
philpem@0 207
philpem@0 208 input branch_predict_taken_d; // Branch is predicted taken in D stage
philpem@0 209 input [`LM32_PC_RNG] branch_predict_address_d; // Branch target address
philpem@0 210
philpem@0 211 `ifdef CFG_FAST_UNCONDITIONAL_BRANCH
philpem@0 212 input branch_taken_x; // Branch instruction in X stage is taken
philpem@0 213 input [`LM32_PC_RNG] branch_target_x; // Target PC of X stage branch instruction
philpem@0 214 `endif
philpem@0 215 input exception_m;
philpem@0 216 input branch_taken_m; // Branch instruction in M stage is taken
philpem@0 217 input branch_mispredict_taken_m; // Branch instruction in M stage is mispredicted as taken
philpem@0 218 input [`LM32_PC_RNG] branch_target_m; // Target PC of M stage branch instruction
philpem@0 219
philpem@0 220 `ifdef CFG_ICACHE_ENABLED
philpem@0 221 input iflush; // Flush instruction cache
philpem@0 222 `endif
philpem@0 223 `ifdef CFG_DCACHE_ENABLED
philpem@0 224 input dcache_restart_request; // Restart instruction that caused a data cache miss
philpem@0 225 input dcache_refill_request; // Request to refill data cache
philpem@0 226 input dcache_refilling;
philpem@0 227 `endif
philpem@0 228
philpem@0 229 `ifdef CFG_IROM_ENABLED
philpem@0 230 input [`LM32_WORD_RNG] irom_store_data_m; // Data from load-store unit
philpem@0 231 input [`LM32_WORD_RNG] irom_address_xm; // Address from load-store unit
philpem@0 232 input irom_we_xm; // Indicates if memory operation is load or store
philpem@0 233 `endif
philpem@0 234
philpem@0 235 `ifdef CFG_IWB_ENABLED
philpem@0 236 input [`LM32_WORD_RNG] i_dat_i; // Instruction Wishbone interface read data
philpem@0 237 input i_ack_i; // Instruction Wishbone interface acknowledgement
philpem@0 238 input i_err_i; // Instruction Wishbone interface error
philpem@0 239 `endif
philpem@0 240
philpem@0 241 `ifdef CFG_HW_DEBUG_ENABLED
philpem@0 242 input jtag_read_enable; // JTAG read memory request
philpem@0 243 input jtag_write_enable; // JTAG write memory request
philpem@0 244 input [`LM32_BYTE_RNG] jtag_write_data; // JTAG wrirte data
philpem@0 245 input [`LM32_WORD_RNG] jtag_address; // JTAG read/write address
philpem@0 246 `endif
philpem@0 247
philpem@0 248 /////////////////////////////////////////////////////
philpem@0 249 // Outputs
philpem@0 250 /////////////////////////////////////////////////////
philpem@0 251
philpem@0 252 output [`LM32_PC_RNG] pc_f; // F stage PC
philpem@0 253 reg [`LM32_PC_RNG] pc_f;
philpem@0 254 output [`LM32_PC_RNG] pc_d; // D stage PC
philpem@0 255 reg [`LM32_PC_RNG] pc_d;
philpem@0 256 output [`LM32_PC_RNG] pc_x; // X stage PC
philpem@0 257 reg [`LM32_PC_RNG] pc_x;
philpem@0 258 output [`LM32_PC_RNG] pc_m; // M stage PC
philpem@0 259 reg [`LM32_PC_RNG] pc_m;
philpem@0 260 output [`LM32_PC_RNG] pc_w; // W stage PC
philpem@0 261 reg [`LM32_PC_RNG] pc_w;
philpem@0 262
philpem@0 263 `ifdef CFG_ICACHE_ENABLED
philpem@0 264 output icache_stall_request; // Instruction cache stall request
philpem@0 265 wire icache_stall_request;
philpem@0 266 output icache_restart_request; // Request to restart instruction that cached instruction cache miss
philpem@0 267 wire icache_restart_request;
philpem@0 268 output icache_refill_request; // Instruction cache refill request
philpem@0 269 wire icache_refill_request;
philpem@0 270 output icache_refilling; // Indicates the icache is refilling
philpem@0 271 wire icache_refilling;
philpem@0 272 `endif
philpem@0 273
philpem@0 274 `ifdef CFG_IROM_ENABLED
philpem@0 275 output [`LM32_WORD_RNG] irom_data_m; // Data to load-store unit on load
philpem@0 276 wire [`LM32_WORD_RNG] irom_data_m;
philpem@0 277 `endif
philpem@0 278
philpem@0 279 `ifdef CFG_IWB_ENABLED
philpem@0 280 output [`LM32_WORD_RNG] i_dat_o; // Instruction Wishbone interface write data
philpem@0 281 `ifdef CFG_HW_DEBUG_ENABLED
philpem@0 282 reg [`LM32_WORD_RNG] i_dat_o;
philpem@0 283 `else
philpem@0 284 wire [`LM32_WORD_RNG] i_dat_o;
philpem@0 285 `endif
philpem@0 286 output [`LM32_WORD_RNG] i_adr_o; // Instruction Wishbone interface address
philpem@0 287 reg [`LM32_WORD_RNG] i_adr_o;
philpem@0 288 output i_cyc_o; // Instruction Wishbone interface cycle
philpem@0 289 reg i_cyc_o;
philpem@0 290 output [`LM32_BYTE_SELECT_RNG] i_sel_o; // Instruction Wishbone interface byte select
philpem@0 291 `ifdef CFG_HW_DEBUG_ENABLED
philpem@0 292 reg [`LM32_BYTE_SELECT_RNG] i_sel_o;
philpem@0 293 `else
philpem@0 294 wire [`LM32_BYTE_SELECT_RNG] i_sel_o;
philpem@0 295 `endif
philpem@0 296 output i_stb_o; // Instruction Wishbone interface strobe
philpem@0 297 reg i_stb_o;
philpem@0 298 output i_we_o; // Instruction Wishbone interface write enable
philpem@0 299 `ifdef CFG_HW_DEBUG_ENABLED
philpem@0 300 reg i_we_o;
philpem@0 301 `else
philpem@0 302 wire i_we_o;
philpem@0 303 `endif
philpem@0 304 output [`LM32_CTYPE_RNG] i_cti_o; // Instruction Wishbone interface cycle type
philpem@0 305 reg [`LM32_CTYPE_RNG] i_cti_o;
philpem@0 306 output i_lock_o; // Instruction Wishbone interface lock bus
philpem@0 307 reg i_lock_o;
philpem@0 308 output [`LM32_BTYPE_RNG] i_bte_o; // Instruction Wishbone interface burst type
philpem@0 309 wire [`LM32_BTYPE_RNG] i_bte_o;
philpem@0 310 `endif
philpem@0 311
philpem@0 312 `ifdef CFG_HW_DEBUG_ENABLED
philpem@0 313 output [`LM32_BYTE_RNG] jtag_read_data; // Data read for JTAG interface
philpem@0 314 reg [`LM32_BYTE_RNG] jtag_read_data;
philpem@0 315 output jtag_access_complete; // Requested memory access by JTAG interface is complete
philpem@0 316 wire jtag_access_complete;
philpem@0 317 `endif
philpem@0 318
philpem@0 319 `ifdef CFG_BUS_ERRORS_ENABLED
philpem@0 320 output bus_error_d; // Indicates a bus error occured while fetching the instruction
philpem@0 321 reg bus_error_d;
philpem@0 322 `endif
philpem@0 323 `ifdef CFG_EBR_POSEDGE_REGISTER_FILE
philpem@0 324 output [`LM32_INSTRUCTION_RNG] instruction_f; // F stage instruction (only to have register indices extracted from)
philpem@0 325 wire [`LM32_INSTRUCTION_RNG] instruction_f;
philpem@0 326 `endif
philpem@0 327 output [`LM32_INSTRUCTION_RNG] instruction_d; // D stage instruction to be decoded
philpem@0 328 reg [`LM32_INSTRUCTION_RNG] instruction_d;
philpem@0 329
philpem@0 330 /////////////////////////////////////////////////////
philpem@0 331 // Internal nets and registers
philpem@0 332 /////////////////////////////////////////////////////
philpem@0 333
philpem@0 334 reg [`LM32_PC_RNG] pc_a; // A stage PC
philpem@0 335
philpem@0 336 `ifdef LM32_CACHE_ENABLED
philpem@0 337 reg [`LM32_PC_RNG] restart_address; // Address to restart from after a cache miss
philpem@0 338 `endif
philpem@0 339
philpem@0 340 `ifdef CFG_ICACHE_ENABLED
philpem@0 341 wire icache_read_enable_f; // Indicates if instruction cache miss is valid
philpem@0 342 wire [`LM32_PC_RNG] icache_refill_address; // Address that caused cache miss
philpem@0 343 reg icache_refill_ready; // Indicates when next word of refill data is ready to be written to cache
philpem@0 344 reg [`LM32_INSTRUCTION_RNG] icache_refill_data; // Next word of refill data, fetched from Wishbone
philpem@0 345 wire [`LM32_INSTRUCTION_RNG] icache_data_f; // Instruction fetched from instruction cache
philpem@0 346 wire [`LM32_CTYPE_RNG] first_cycle_type; // First Wishbone cycle type
philpem@0 347 wire [`LM32_CTYPE_RNG] next_cycle_type; // Next Wishbone cycle type
philpem@0 348 wire last_word; // Indicates if this is the last word in the cache line
philpem@0 349 wire [`LM32_PC_RNG] first_address; // First cache refill address
philpem@0 350 `else
philpem@0 351 `ifdef CFG_IWB_ENABLED
philpem@0 352 reg [`LM32_INSTRUCTION_RNG] wb_data_f; // Instruction fetched from Wishbone
philpem@0 353 `endif
philpem@0 354 `endif
philpem@0 355 `ifdef CFG_IROM_ENABLED
philpem@0 356 wire irom_select_a; // Indicates if A stage PC maps to a ROM address
philpem@0 357 reg irom_select_f; // Indicates if F stage PC maps to a ROM address
philpem@0 358 wire [`LM32_INSTRUCTION_RNG] irom_data_f; // Instruction fetched from ROM
philpem@0 359 `endif
philpem@0 360 `ifdef CFG_EBR_POSEDGE_REGISTER_FILE
philpem@0 361 `else
philpem@0 362 wire [`LM32_INSTRUCTION_RNG] instruction_f; // F stage instruction
philpem@0 363 `endif
philpem@0 364 `ifdef CFG_BUS_ERRORS_ENABLED
philpem@0 365 reg bus_error_f; // Indicates if a bus error occured while fetching the instruction in the F stage
philpem@0 366 `endif
philpem@0 367
philpem@0 368 `ifdef CFG_HW_DEBUG_ENABLED
philpem@0 369 reg jtag_access; // Indicates if a JTAG WB access is in progress
philpem@0 370 `endif
philpem@0 371
philpem@26 372 `ifdef CFG_ALTERNATE_EBA
philpem@26 373 reg alternate_eba_taken;
philpem@26 374 `endif
philpem@26 375
philpem@0 376 /////////////////////////////////////////////////////
philpem@0 377 // Functions
philpem@0 378 /////////////////////////////////////////////////////
philpem@0 379
philpem@0 380 `include "lm32_functions.v"
philpem@0 381
philpem@0 382 /////////////////////////////////////////////////////
philpem@0 383 // Instantiations
philpem@0 384 /////////////////////////////////////////////////////
philpem@0 385
philpem@0 386 // Instruction ROM
philpem@0 387 `ifdef CFG_IROM_ENABLED
philpem@0 388 pmi_ram_dp_true
philpem@0 389 #(
philpem@0 390 // ----- Parameters -------
philpem@0 391 .pmi_family (`LATTICE_FAMILY),
philpem@0 392
philpem@0 393 //.pmi_addr_depth_a (1 << (clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)),
philpem@0 394 //.pmi_addr_width_a ((clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)),
philpem@0 395 //.pmi_data_width_a (`LM32_WORD_WIDTH),
philpem@0 396 //.pmi_addr_depth_b (1 << (clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)),
philpem@0 397 //.pmi_addr_width_b ((clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)),
philpem@0 398 //.pmi_data_width_b (`LM32_WORD_WIDTH),
philpem@0 399
philpem@0 400 .pmi_addr_depth_a (`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1),
philpem@0 401 .pmi_addr_width_a (clogb2_v1(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)),
philpem@0 402 .pmi_data_width_a (`LM32_WORD_WIDTH),
philpem@0 403 .pmi_addr_depth_b (`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1),
philpem@0 404 .pmi_addr_width_b (clogb2_v1(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)),
philpem@0 405 .pmi_data_width_b (`LM32_WORD_WIDTH),
philpem@0 406
philpem@0 407 .pmi_regmode_a ("noreg"),
philpem@0 408 .pmi_regmode_b ("noreg"),
philpem@0 409 .pmi_gsr ("enable"),
philpem@0 410 .pmi_resetmode ("sync"),
philpem@0 411 .pmi_init_file (`CFG_IROM_INIT_FILE),
philpem@0 412 .pmi_init_file_format (`CFG_IROM_INIT_FILE_FORMAT),
philpem@0 413 .module_type ("pmi_ram_dp_true")
philpem@0 414 )
philpem@0 415 ram (
philpem@0 416 // ----- Inputs -------
philpem@0 417 .ClockA (clk_i),
philpem@0 418 .ClockB (clk_i),
philpem@0 419 .ResetA (rst_i),
philpem@0 420 .ResetB (rst_i),
philpem@0 421 .DataInA ({32{1'b0}}),
philpem@0 422 .DataInB (irom_store_data_m),
philpem@26 423 .AddressA (pc_a[clogb2_v1(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)+2-1:2]),
philpem@26 424 .AddressB (irom_address_xm[clogb2_v1(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)+2-1:2]),
philpem@0 425 .ClockEnA (!stall_a),
philpem@0 426 .ClockEnB (!stall_x || !stall_m),
philpem@0 427 .WrA (`FALSE),
philpem@0 428 .WrB (irom_we_xm),
philpem@0 429 // ----- Outputs -------
philpem@0 430 .QA (irom_data_f),
philpem@0 431 .QB (irom_data_m)
philpem@0 432 );
philpem@0 433 `endif
philpem@0 434
philpem@0 435 `ifdef CFG_ICACHE_ENABLED
philpem@0 436 // Instruction cache
philpem@0 437 lm32_icache #(
philpem@0 438 .associativity (associativity),
philpem@0 439 .sets (sets),
philpem@0 440 .bytes_per_line (bytes_per_line),
philpem@0 441 .base_address (base_address),
philpem@0 442 .limit (limit)
philpem@0 443 ) icache (
philpem@0 444 // ----- Inputs -----
philpem@0 445 .clk_i (clk_i),
philpem@0 446 .rst_i (rst_i),
philpem@0 447 .stall_a (stall_a),
philpem@0 448 .stall_f (stall_f),
philpem@0 449 .branch_predict_taken_d (branch_predict_taken_d),
philpem@0 450 .valid_d (valid_d),
philpem@0 451 .address_a (pc_a),
philpem@0 452 .address_f (pc_f),
philpem@0 453 .read_enable_f (icache_read_enable_f),
philpem@0 454 .refill_ready (icache_refill_ready),
philpem@0 455 .refill_data (icache_refill_data),
philpem@0 456 .iflush (iflush),
philpem@0 457 // ----- Outputs -----
philpem@0 458 .stall_request (icache_stall_request),
philpem@0 459 .restart_request (icache_restart_request),
philpem@0 460 .refill_request (icache_refill_request),
philpem@0 461 .refill_address (icache_refill_address),
philpem@0 462 .refilling (icache_refilling),
philpem@0 463 .inst (icache_data_f)
philpem@0 464 );
philpem@0 465 `endif
philpem@0 466
philpem@0 467 /////////////////////////////////////////////////////
philpem@0 468 // Combinational Logic
philpem@0 469 /////////////////////////////////////////////////////
philpem@0 470
philpem@0 471 `ifdef CFG_ICACHE_ENABLED
philpem@0 472 // Generate signal that indicates when instruction cache misses are valid
philpem@0 473 assign icache_read_enable_f = (valid_f == `TRUE)
philpem@0 474 && (kill_f == `FALSE)
philpem@0 475 `ifdef CFG_DCACHE_ENABLED
philpem@0 476 && (dcache_restart_request == `FALSE)
philpem@0 477 `endif
philpem@0 478 `ifdef CFG_IROM_ENABLED
philpem@0 479 && (irom_select_f == `FALSE)
philpem@0 480 `endif
philpem@0 481 ;
philpem@0 482 `endif
philpem@0 483
philpem@0 484 // Compute address of next instruction to fetch
philpem@0 485 always @(*)
philpem@0 486 begin
philpem@0 487 // The request from the latest pipeline stage must take priority
philpem@0 488 `ifdef CFG_DCACHE_ENABLED
philpem@0 489 if (dcache_restart_request == `TRUE)
philpem@0 490 pc_a = restart_address;
philpem@0 491 else
philpem@0 492 `endif
philpem@0 493 if (branch_taken_m == `TRUE)
philpem@0 494 if ((branch_mispredict_taken_m == `TRUE) && (exception_m == `FALSE))
philpem@0 495 pc_a = pc_x;
philpem@0 496 else
philpem@0 497 pc_a = branch_target_m;
philpem@0 498 `ifdef CFG_FAST_UNCONDITIONAL_BRANCH
philpem@0 499 else if (branch_taken_x == `TRUE)
philpem@0 500 pc_a = branch_target_x;
philpem@0 501 `endif
philpem@0 502 else
philpem@0 503 if ( (valid_d == `TRUE) && (branch_predict_taken_d == `TRUE) )
philpem@0 504 pc_a = branch_predict_address_d;
philpem@0 505 else
philpem@0 506 `ifdef CFG_ICACHE_ENABLED
philpem@0 507 if (icache_restart_request == `TRUE)
philpem@0 508 pc_a = restart_address;
philpem@0 509 else
philpem@0 510 `endif
philpem@26 511 pc_a = pc_f + 1'b1;
philpem@0 512 end
philpem@0 513
philpem@0 514 // Select where instruction should be fetched from
philpem@0 515 `ifdef CFG_IROM_ENABLED
philpem@0 516 assign irom_select_a = ({pc_a, 2'b00} >= `CFG_IROM_BASE_ADDRESS) && ({pc_a, 2'b00} <= `CFG_IROM_LIMIT);
philpem@0 517 `endif
philpem@0 518
philpem@0 519 // Select instruction from selected source
philpem@0 520 `ifdef CFG_ICACHE_ENABLED
philpem@0 521 `ifdef CFG_IROM_ENABLED
philpem@0 522 assign instruction_f = irom_select_f == `TRUE ? irom_data_f : icache_data_f;
philpem@0 523 `else
philpem@0 524 assign instruction_f = icache_data_f;
philpem@0 525 `endif
philpem@0 526 `else
philpem@0 527 `ifdef CFG_IROM_ENABLED
philpem@0 528 `ifdef CFG_IWB_ENABLED
philpem@0 529 assign instruction_f = irom_select_f == `TRUE ? irom_data_f : wb_data_f;
philpem@0 530 `else
philpem@0 531 assign instruction_f = irom_data_f;
philpem@0 532 `endif
philpem@0 533 `else
philpem@0 534 assign instruction_f = wb_data_f;
philpem@0 535 `endif
philpem@0 536 `endif
philpem@0 537
philpem@0 538 // Unused/constant Wishbone signals
philpem@0 539 `ifdef CFG_IWB_ENABLED
philpem@0 540 `ifdef CFG_HW_DEBUG_ENABLED
philpem@0 541 `else
philpem@0 542 assign i_dat_o = 32'd0;
philpem@0 543 assign i_we_o = `FALSE;
philpem@0 544 assign i_sel_o = 4'b1111;
philpem@0 545 `endif
philpem@0 546 assign i_bte_o = `LM32_BTYPE_LINEAR;
philpem@0 547 `endif
philpem@0 548
philpem@0 549 `ifdef CFG_ICACHE_ENABLED
philpem@0 550 // Determine parameters for next cache refill Wishbone access
philpem@0 551 generate
philpem@0 552 case (bytes_per_line)
philpem@0 553 4:
philpem@0 554 begin
philpem@0 555 assign first_cycle_type = `LM32_CTYPE_END;
philpem@0 556 assign next_cycle_type = `LM32_CTYPE_END;
philpem@0 557 assign last_word = `TRUE;
philpem@0 558 assign first_address = icache_refill_address;
philpem@0 559 end
philpem@0 560 8:
philpem@0 561 begin
philpem@0 562 assign first_cycle_type = `LM32_CTYPE_INCREMENTING;
philpem@0 563 assign next_cycle_type = `LM32_CTYPE_END;
philpem@0 564 assign last_word = i_adr_o[addr_offset_msb:addr_offset_lsb] == 1'b1;
philpem@0 565 assign first_address = {icache_refill_address[`LM32_PC_WIDTH+2-1:addr_offset_msb+1], {addr_offset_width{1'b0}}};
philpem@0 566 end
philpem@0 567 16:
philpem@0 568 begin
philpem@0 569 assign first_cycle_type = `LM32_CTYPE_INCREMENTING;
philpem@0 570 assign next_cycle_type = i_adr_o[addr_offset_msb] == 1'b1 ? `LM32_CTYPE_END : `LM32_CTYPE_INCREMENTING;
philpem@0 571 assign last_word = i_adr_o[addr_offset_msb:addr_offset_lsb] == 2'b11;
philpem@0 572 assign first_address = {icache_refill_address[`LM32_PC_WIDTH+2-1:addr_offset_msb+1], {addr_offset_width{1'b0}}};
philpem@0 573 end
philpem@0 574 endcase
philpem@0 575 endgenerate
philpem@0 576 `endif
philpem@0 577
philpem@0 578 /////////////////////////////////////////////////////
philpem@0 579 // Sequential Logic
philpem@0 580 /////////////////////////////////////////////////////
philpem@0 581
philpem@0 582 // PC
philpem@0 583 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
philpem@26 584 begin
philpem@26 585 if (rst_i == `TRUE)
philpem@26 586 begin
philpem@26 587 `ifdef CFG_DEBUG_ENABLED
philpem@26 588 `ifdef CFG_ALTERNATE_EBA
philpem@26 589 if (at_debug == `TRUE)
philpem@27 590 pc_f <= (`CFG_DEBA_RESET-4)/4;
philpem@26 591 else
philpem@27 592 pc_f <= (`CFG_EBA_RESET-4)/4;
philpem@26 593 `else
philpem@27 594 pc_f <= (`CFG_EBA_RESET-4)/4;
philpem@26 595 `endif
philpem@26 596 `else
philpem@27 597 pc_f <= (`CFG_EBA_RESET-4)/4;
philpem@26 598 `endif
philpem@27 599 pc_d <= {`LM32_PC_WIDTH{1'b0}};
philpem@27 600 pc_x <= {`LM32_PC_WIDTH{1'b0}};
philpem@27 601 pc_m <= {`LM32_PC_WIDTH{1'b0}};
philpem@27 602 pc_w <= {`LM32_PC_WIDTH{1'b0}};
philpem@26 603 end
philpem@26 604 else
philpem@26 605 begin
philpem@26 606 if (stall_f == `FALSE)
philpem@27 607 pc_f <= pc_a;
philpem@26 608 if (stall_d == `FALSE)
philpem@27 609 pc_d <= pc_f;
philpem@26 610 if (stall_x == `FALSE)
philpem@27 611 pc_x <= pc_d;
philpem@26 612 if (stall_m == `FALSE)
philpem@27 613 pc_m <= pc_x;
philpem@27 614 pc_w <= pc_m;
philpem@26 615 end
philpem@26 616 end
philpem@0 617
philpem@0 618 `ifdef LM32_CACHE_ENABLED
philpem@0 619 // Address to restart from after a cache miss has been handled
philpem@0 620 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
philpem@0 621 begin
philpem@0 622 if (rst_i == `TRUE)
philpem@27 623 restart_address <= {`LM32_PC_WIDTH{1'b0}};
philpem@0 624 else
philpem@0 625 begin
philpem@0 626 `ifdef CFG_DCACHE_ENABLED
philpem@0 627 `ifdef CFG_ICACHE_ENABLED
philpem@0 628 // D-cache restart address must take priority, otherwise instructions will be lost
philpem@0 629 if (dcache_refill_request == `TRUE)
philpem@27 630 restart_address <= pc_w;
philpem@0 631 else if ((icache_refill_request == `TRUE) && (!dcache_refilling) && (!dcache_restart_request))
philpem@27 632 restart_address <= icache_refill_address;
philpem@0 633 `else
philpem@0 634 if (dcache_refill_request == `TRUE)
philpem@27 635 restart_address <= pc_w;
philpem@0 636 `endif
philpem@0 637 `else
philpem@0 638 `ifdef CFG_ICACHE_ENABLED
philpem@0 639 if (icache_refill_request == `TRUE)
philpem@27 640 restart_address <= icache_refill_address;
philpem@0 641 `endif
philpem@0 642 `endif
philpem@0 643 end
philpem@0 644 end
philpem@0 645 `endif
philpem@0 646
philpem@0 647 // Record where instruction was fetched from
philpem@0 648 `ifdef CFG_IROM_ENABLED
philpem@0 649 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
philpem@0 650 begin
philpem@0 651 if (rst_i == `TRUE)
philpem@27 652 irom_select_f <= `FALSE;
philpem@0 653 else
philpem@0 654 begin
philpem@0 655 if (stall_f == `FALSE)
philpem@27 656 irom_select_f <= irom_select_a;
philpem@0 657 end
philpem@0 658 end
philpem@0 659 `endif
philpem@0 660
philpem@0 661 `ifdef CFG_HW_DEBUG_ENABLED
philpem@0 662 assign jtag_access_complete = (i_cyc_o == `TRUE) && ((i_ack_i == `TRUE) || (i_err_i == `TRUE)) && (jtag_access == `TRUE);
philpem@0 663 always @(*)
philpem@0 664 begin
philpem@0 665 case (jtag_address[1:0])
philpem@0 666 2'b00: jtag_read_data = i_dat_i[`LM32_BYTE_3_RNG];
philpem@0 667 2'b01: jtag_read_data = i_dat_i[`LM32_BYTE_2_RNG];
philpem@0 668 2'b10: jtag_read_data = i_dat_i[`LM32_BYTE_1_RNG];
philpem@0 669 2'b11: jtag_read_data = i_dat_i[`LM32_BYTE_0_RNG];
philpem@0 670 endcase
philpem@0 671 end
philpem@0 672 `endif
philpem@0 673
philpem@0 674 `ifdef CFG_IWB_ENABLED
philpem@0 675 // Instruction Wishbone interface
philpem@0 676 `ifdef CFG_ICACHE_ENABLED
philpem@0 677 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
philpem@0 678 begin
philpem@0 679 if (rst_i == `TRUE)
philpem@0 680 begin
philpem@27 681 i_cyc_o <= `FALSE;
philpem@27 682 i_stb_o <= `FALSE;
philpem@27 683 i_adr_o <= {`LM32_WORD_WIDTH{1'b0}};
philpem@27 684 i_cti_o <= `LM32_CTYPE_END;
philpem@27 685 i_lock_o <= `FALSE;
philpem@27 686 icache_refill_data <= {`LM32_INSTRUCTION_WIDTH{1'b0}};
philpem@27 687 icache_refill_ready <= `FALSE;
philpem@0 688 `ifdef CFG_BUS_ERRORS_ENABLED
philpem@27 689 bus_error_f <= `FALSE;
philpem@0 690 `endif
philpem@0 691 `ifdef CFG_HW_DEBUG_ENABLED
philpem@27 692 i_we_o <= `FALSE;
philpem@27 693 i_sel_o <= 4'b1111;
philpem@27 694 jtag_access <= `FALSE;
philpem@0 695 `endif
philpem@0 696 end
philpem@0 697 else
philpem@0 698 begin
philpem@27 699 icache_refill_ready <= `FALSE;
philpem@0 700 // Is a cycle in progress?
philpem@0 701 if (i_cyc_o == `TRUE)
philpem@0 702 begin
philpem@0 703 // Has cycle completed?
philpem@0 704 if ((i_ack_i == `TRUE) || (i_err_i == `TRUE))
philpem@0 705 begin
philpem@0 706 `ifdef CFG_HW_DEBUG_ENABLED
philpem@0 707 if (jtag_access == `TRUE)
philpem@0 708 begin
philpem@27 709 i_cyc_o <= `FALSE;
philpem@27 710 i_stb_o <= `FALSE;
philpem@27 711 i_we_o <= `FALSE;
philpem@27 712 jtag_access <= `FALSE;
philpem@0 713 end
philpem@0 714 else
philpem@0 715 `endif
philpem@0 716 begin
philpem@0 717 if (last_word == `TRUE)
philpem@0 718 begin
philpem@0 719 // Cache line fill complete
philpem@27 720 i_cyc_o <= `FALSE;
philpem@27 721 i_stb_o <= `FALSE;
philpem@27 722 i_lock_o <= `FALSE;
philpem@0 723 end
philpem@0 724 // Fetch next word in cache line
philpem@27 725 i_adr_o[addr_offset_msb:addr_offset_lsb] <= i_adr_o[addr_offset_msb:addr_offset_lsb] + 1'b1;
philpem@27 726 i_cti_o <= next_cycle_type;
philpem@0 727 // Write fetched data into instruction cache
philpem@27 728 icache_refill_ready <= `TRUE;
philpem@27 729 icache_refill_data <= i_dat_i;
philpem@0 730 end
philpem@0 731 end
philpem@0 732 `ifdef CFG_BUS_ERRORS_ENABLED
philpem@0 733 if (i_err_i == `TRUE)
philpem@0 734 begin
philpem@27 735 bus_error_f <= `TRUE;
philpem@0 736 $display ("Instruction bus error. Address: %x", i_adr_o);
philpem@0 737 end
philpem@0 738 `endif
philpem@0 739 end
philpem@0 740 else
philpem@0 741 begin
philpem@0 742 if ((icache_refill_request == `TRUE) && (icache_refill_ready == `FALSE))
philpem@0 743 begin
philpem@0 744 // Read first word of cache line
philpem@0 745 `ifdef CFG_HW_DEBUG_ENABLED
philpem@27 746 i_sel_o <= 4'b1111;
philpem@0 747 `endif
philpem@27 748 i_adr_o <= {first_address, 2'b00};
philpem@27 749 i_cyc_o <= `TRUE;
philpem@27 750 i_stb_o <= `TRUE;
philpem@27 751 i_cti_o <= first_cycle_type;
philpem@27 752 //i_lock_o <= `TRUE;
philpem@0 753 `ifdef CFG_BUS_ERRORS_ENABLED
philpem@27 754 bus_error_f <= `FALSE;
philpem@0 755 `endif
philpem@0 756 end
philpem@0 757 `ifdef CFG_HW_DEBUG_ENABLED
philpem@0 758 else
philpem@0 759 begin
philpem@0 760 if ((jtag_read_enable == `TRUE) || (jtag_write_enable == `TRUE))
philpem@0 761 begin
philpem@0 762 case (jtag_address[1:0])
philpem@27 763 2'b00: i_sel_o <= 4'b1000;
philpem@27 764 2'b01: i_sel_o <= 4'b0100;
philpem@27 765 2'b10: i_sel_o <= 4'b0010;
philpem@27 766 2'b11: i_sel_o <= 4'b0001;
philpem@0 767 endcase
philpem@27 768 i_adr_o <= jtag_address;
philpem@27 769 i_dat_o <= {4{jtag_write_data}};
philpem@27 770 i_cyc_o <= `TRUE;
philpem@27 771 i_stb_o <= `TRUE;
philpem@27 772 i_we_o <= jtag_write_enable;
philpem@27 773 i_cti_o <= `LM32_CTYPE_END;
philpem@27 774 jtag_access <= `TRUE;
philpem@0 775 end
philpem@0 776 end
philpem@0 777 `endif
philpem@0 778 `ifdef CFG_BUS_ERRORS_ENABLED
philpem@0 779 // Clear bus error when exception taken, otherwise they would be
philpem@0 780 // continually generated if exception handler is cached
philpem@0 781 `ifdef CFG_FAST_UNCONDITIONAL_BRANCH
philpem@0 782 if (branch_taken_x == `TRUE)
philpem@27 783 bus_error_f <= `FALSE;
philpem@0 784 `endif
philpem@0 785 if (branch_taken_m == `TRUE)
philpem@27 786 bus_error_f <= `FALSE;
philpem@0 787 `endif
philpem@0 788 end
philpem@0 789 end
philpem@0 790 end
philpem@0 791 `else
philpem@0 792 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
philpem@0 793 begin
philpem@0 794 if (rst_i == `TRUE)
philpem@0 795 begin
philpem@27 796 i_cyc_o <= `FALSE;
philpem@27 797 i_stb_o <= `FALSE;
philpem@27 798 i_adr_o <= {`LM32_WORD_WIDTH{1'b0}};
philpem@27 799 i_cti_o <= `LM32_CTYPE_END;
philpem@27 800 i_lock_o <= `FALSE;
philpem@27 801 wb_data_f <= {`LM32_INSTRUCTION_WIDTH{1'b0}};
philpem@0 802 `ifdef CFG_BUS_ERRORS_ENABLED
philpem@27 803 bus_error_f <= `FALSE;
philpem@0 804 `endif
philpem@0 805 end
philpem@0 806 else
philpem@0 807 begin
philpem@0 808 // Is a cycle in progress?
philpem@0 809 if (i_cyc_o == `TRUE)
philpem@0 810 begin
philpem@0 811 // Has cycle completed?
philpem@0 812 if((i_ack_i == `TRUE) || (i_err_i == `TRUE))
philpem@0 813 begin
philpem@0 814 // Cycle complete
philpem@27 815 i_cyc_o <= `FALSE;
philpem@27 816 i_stb_o <= `FALSE;
philpem@0 817 // Register fetched instruction
philpem@27 818 wb_data_f <= i_dat_i;
philpem@0 819 end
philpem@0 820 `ifdef CFG_BUS_ERRORS_ENABLED
philpem@0 821 if (i_err_i == `TRUE)
philpem@0 822 begin
philpem@27 823 bus_error_f <= `TRUE;
philpem@0 824 $display ("Instruction bus error. Address: %x", i_adr_o);
philpem@0 825 end
philpem@0 826 `endif
philpem@0 827 end
philpem@0 828 else
philpem@0 829 begin
philpem@0 830 // Wait for an instruction fetch from an external address
philpem@0 831 if ( (stall_a == `FALSE)
philpem@0 832 `ifdef CFG_IROM_ENABLED
philpem@0 833 && (irom_select_a == `FALSE)
philpem@0 834 `endif
philpem@0 835 )
philpem@0 836 begin
philpem@0 837 // Fetch instruction
philpem@0 838 `ifdef CFG_HW_DEBUG_ENABLED
philpem@27 839 i_sel_o <= 4'b1111;
philpem@0 840 `endif
philpem@27 841 i_adr_o <= {pc_a, 2'b00};
philpem@27 842 i_cyc_o <= `TRUE;
philpem@27 843 i_stb_o <= `TRUE;
philpem@0 844 `ifdef CFG_BUS_ERRORS_ENABLED
philpem@27 845 bus_error_f <= `FALSE;
philpem@0 846 `endif
philpem@0 847 end
philpem@0 848 else
philpem@0 849 begin
philpem@0 850 if ( (stall_a == `FALSE)
philpem@0 851 `ifdef CFG_IROM_ENABLED
philpem@0 852 && (irom_select_a == `TRUE)
philpem@0 853 `endif
philpem@0 854 )
philpem@0 855 begin
philpem@0 856 `ifdef CFG_BUS_ERRORS_ENABLED
philpem@27 857 bus_error_f <= `FALSE;
philpem@0 858 `endif
philpem@0 859 end
philpem@0 860 end
philpem@0 861 end
philpem@0 862 end
philpem@0 863 end
philpem@0 864 `endif
philpem@0 865 `endif
philpem@0 866
philpem@0 867 // Instruction register
philpem@0 868 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
philpem@0 869 begin
philpem@0 870 if (rst_i == `TRUE)
philpem@0 871 begin
philpem@27 872 instruction_d <= {`LM32_INSTRUCTION_WIDTH{1'b0}};
philpem@0 873 `ifdef CFG_BUS_ERRORS_ENABLED
philpem@27 874 bus_error_d <= `FALSE;
philpem@0 875 `endif
philpem@0 876 end
philpem@0 877 else
philpem@0 878 begin
philpem@0 879 if (stall_d == `FALSE)
philpem@0 880 begin
philpem@27 881 instruction_d <= instruction_f;
philpem@0 882 `ifdef CFG_BUS_ERRORS_ENABLED
philpem@27 883 bus_error_d <= bus_error_f;
philpem@0 884 `endif
philpem@0 885 end
philpem@0 886 end
philpem@0 887 end
philpem@0 888
philpem@0 889 endmodule