// ================================================================== // >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<< // ------------------------------------------------------------------ // Copyright (c) 2006-2011 by Lattice Semiconductor Corporation // ALL RIGHTS RESERVED // ------------------------------------------------------------------ // // IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM. // // Permission: // // Lattice Semiconductor grants permission to use this code // pursuant to the terms of the Lattice Semiconductor Corporation // Open Source License Agreement. // // Disclaimer: // // Lattice Semiconductor provides no warranty regarding the use or // functionality of this code. It is the user's responsibility to // verify the user's design for consistency and functionality through // the use of formal verification methods. // // -------------------------------------------------------------------- // // Lattice Semiconductor Corporation // 5555 NE Moore Court // Hillsboro, OR 97214 // U.S.A // // TEL: 1-800-Lattice (USA and Canada) // 503-286-8001 (other locations) // // web: http://www.latticesemi.com/ // email: techsupport@latticesemi.com // // -------------------------------------------------------------------- // FILE DETAILS // Project : LatticeMico32 // File : lm32_instruction_unit.v // Title : Instruction unit // Dependencies : lm32_include.v // Version : 6.1.17 // : Initial Release // Version : 7.0SP2, 3.0 // : No Change // Version : 3.1 // : Support for static branch prediction is added. Fetching of // : instructions can also be altered by branches predicted in D // : stage of pipeline, and mispredicted branches in the X and M // : stages of the pipeline. // Version : 3.2 // : EBRs use SYNC resets instead of ASYNC resets. // Version : 3.3 // : Support for a non-cacheable Instruction Memory that has a // : single-cycle access latency. This memory can be accessed by // : data port of LM32 (so that debugger has access to it). // Version : 3.4 // : No change // Version : 3.5 // : Bug fix: Inline memory is correctly generated if it is not a // : power-of-two. // : Bug fix: Fixed a bug that caused LM32 (configured without // : instruction cache) to lock up in to an infinite loop due to a // : instruction bus error when EBA was set to instruction inline // : memory. // Version : 3.8 // : Feature: Support for dynamically switching EBA to DEBA via a // : GPIO. // ============================================================================= `include "lm32_include.v" ///////////////////////////////////////////////////// // Module interface ///////////////////////////////////////////////////// module lm32_instruction_unit ( // ----- Inputs ------- clk_i, rst_i, `ifdef CFG_DEBUG_ENABLED `ifdef CFG_ALTERNATE_EBA at_debug, `endif `endif // From pipeline stall_a, stall_f, stall_d, stall_x, stall_m, valid_f, valid_d, kill_f, branch_predict_taken_d, branch_predict_address_d, `ifdef CFG_FAST_UNCONDITIONAL_BRANCH branch_taken_x, branch_target_x, `endif exception_m, branch_taken_m, branch_mispredict_taken_m, branch_target_m, `ifdef CFG_ICACHE_ENABLED iflush, `endif `ifdef CFG_DCACHE_ENABLED dcache_restart_request, dcache_refill_request, dcache_refilling, `endif `ifdef CFG_IROM_ENABLED irom_store_data_m, irom_address_xm, irom_we_xm, `endif `ifdef CFG_IWB_ENABLED // From Wishbone i_dat_i, i_ack_i, i_err_i, `endif `ifdef CFG_HW_DEBUG_ENABLED jtag_read_enable, jtag_write_enable, jtag_write_data, jtag_address, `endif // ----- Outputs ------- // To pipeline pc_f, pc_d, pc_x, pc_m, pc_w, `ifdef CFG_ICACHE_ENABLED icache_stall_request, icache_restart_request, icache_refill_request, icache_refilling, `endif `ifdef CFG_IROM_ENABLED irom_data_m, `endif `ifdef CFG_IWB_ENABLED // To Wishbone i_dat_o, i_adr_o, i_cyc_o, i_sel_o, i_stb_o, i_we_o, i_cti_o, i_lock_o, i_bte_o, `endif `ifdef CFG_HW_DEBUG_ENABLED jtag_read_data, jtag_access_complete, `endif `ifdef CFG_BUS_ERRORS_ENABLED bus_error_d, `endif `ifdef CFG_EBR_POSEDGE_REGISTER_FILE instruction_f, `endif instruction_d ); ///////////////////////////////////////////////////// // Parameters ///////////////////////////////////////////////////// parameter associativity = 1; // Associativity of the cache (Number of ways) parameter sets = 512; // Number of sets parameter bytes_per_line = 16; // Number of bytes per cache line parameter base_address = 0; // Base address of cachable memory parameter limit = 0; // Limit (highest address) of cachable memory // For bytes_per_line == 4, we set 1 so part-select range isn't reversed, even though not really used localparam addr_offset_width = bytes_per_line == 4 ? 1 : clogb2(bytes_per_line)-1-2; localparam addr_offset_lsb = 2; localparam addr_offset_msb = (addr_offset_lsb+addr_offset_width-1); ///////////////////////////////////////////////////// // Inputs ///////////////////////////////////////////////////// input clk_i; // Clock input rst_i; // Reset `ifdef CFG_DEBUG_ENABLED `ifdef CFG_ALTERNATE_EBA input at_debug; // GPIO input that maps EBA to DEBA `endif `endif input stall_a; // Stall A stage instruction input stall_f; // Stall F stage instruction input stall_d; // Stall D stage instruction input stall_x; // Stall X stage instruction input stall_m; // Stall M stage instruction input valid_f; // Instruction in F stage is valid input valid_d; // Instruction in D stage is valid input kill_f; // Kill instruction in F stage input branch_predict_taken_d; // Branch is predicted taken in D stage input [`LM32_PC_RNG] branch_predict_address_d; // Branch target address `ifdef CFG_FAST_UNCONDITIONAL_BRANCH input branch_taken_x; // Branch instruction in X stage is taken input [`LM32_PC_RNG] branch_target_x; // Target PC of X stage branch instruction `endif input exception_m; input branch_taken_m; // Branch instruction in M stage is taken input branch_mispredict_taken_m; // Branch instruction in M stage is mispredicted as taken input [`LM32_PC_RNG] branch_target_m; // Target PC of M stage branch instruction `ifdef CFG_ICACHE_ENABLED input iflush; // Flush instruction cache `endif `ifdef CFG_DCACHE_ENABLED input dcache_restart_request; // Restart instruction that caused a data cache miss input dcache_refill_request; // Request to refill data cache input dcache_refilling; `endif `ifdef CFG_IROM_ENABLED input [`LM32_WORD_RNG] irom_store_data_m; // Data from load-store unit input [`LM32_WORD_RNG] irom_address_xm; // Address from load-store unit input irom_we_xm; // Indicates if memory operation is load or store `endif `ifdef CFG_IWB_ENABLED input [`LM32_WORD_RNG] i_dat_i; // Instruction Wishbone interface read data input i_ack_i; // Instruction Wishbone interface acknowledgement input i_err_i; // Instruction Wishbone interface error `endif `ifdef CFG_HW_DEBUG_ENABLED input jtag_read_enable; // JTAG read memory request input jtag_write_enable; // JTAG write memory request input [`LM32_BYTE_RNG] jtag_write_data; // JTAG wrirte data input [`LM32_WORD_RNG] jtag_address; // JTAG read/write address `endif ///////////////////////////////////////////////////// // Outputs ///////////////////////////////////////////////////// output [`LM32_PC_RNG] pc_f; // F stage PC reg [`LM32_PC_RNG] pc_f; output [`LM32_PC_RNG] pc_d; // D stage PC reg [`LM32_PC_RNG] pc_d; output [`LM32_PC_RNG] pc_x; // X stage PC reg [`LM32_PC_RNG] pc_x; output [`LM32_PC_RNG] pc_m; // M stage PC reg [`LM32_PC_RNG] pc_m; output [`LM32_PC_RNG] pc_w; // W stage PC reg [`LM32_PC_RNG] pc_w; `ifdef CFG_ICACHE_ENABLED output icache_stall_request; // Instruction cache stall request wire icache_stall_request; output icache_restart_request; // Request to restart instruction that cached instruction cache miss wire icache_restart_request; output icache_refill_request; // Instruction cache refill request wire icache_refill_request; output icache_refilling; // Indicates the icache is refilling wire icache_refilling; `endif `ifdef CFG_IROM_ENABLED output [`LM32_WORD_RNG] irom_data_m; // Data to load-store unit on load wire [`LM32_WORD_RNG] irom_data_m; `endif `ifdef CFG_IWB_ENABLED output [`LM32_WORD_RNG] i_dat_o; // Instruction Wishbone interface write data `ifdef CFG_HW_DEBUG_ENABLED reg [`LM32_WORD_RNG] i_dat_o; `else wire [`LM32_WORD_RNG] i_dat_o; `endif output [`LM32_WORD_RNG] i_adr_o; // Instruction Wishbone interface address reg [`LM32_WORD_RNG] i_adr_o; output i_cyc_o; // Instruction Wishbone interface cycle reg i_cyc_o; output [`LM32_BYTE_SELECT_RNG] i_sel_o; // Instruction Wishbone interface byte select `ifdef CFG_HW_DEBUG_ENABLED reg [`LM32_BYTE_SELECT_RNG] i_sel_o; `else wire [`LM32_BYTE_SELECT_RNG] i_sel_o; `endif output i_stb_o; // Instruction Wishbone interface strobe reg i_stb_o; output i_we_o; // Instruction Wishbone interface write enable `ifdef CFG_HW_DEBUG_ENABLED reg i_we_o; `else wire i_we_o; `endif output [`LM32_CTYPE_RNG] i_cti_o; // Instruction Wishbone interface cycle type reg [`LM32_CTYPE_RNG] i_cti_o; output i_lock_o; // Instruction Wishbone interface lock bus reg i_lock_o; output [`LM32_BTYPE_RNG] i_bte_o; // Instruction Wishbone interface burst type wire [`LM32_BTYPE_RNG] i_bte_o; `endif `ifdef CFG_HW_DEBUG_ENABLED output [`LM32_BYTE_RNG] jtag_read_data; // Data read for JTAG interface reg [`LM32_BYTE_RNG] jtag_read_data; output jtag_access_complete; // Requested memory access by JTAG interface is complete wire jtag_access_complete; `endif `ifdef CFG_BUS_ERRORS_ENABLED output bus_error_d; // Indicates a bus error occured while fetching the instruction reg bus_error_d; `endif `ifdef CFG_EBR_POSEDGE_REGISTER_FILE output [`LM32_INSTRUCTION_RNG] instruction_f; // F stage instruction (only to have register indices extracted from) wire [`LM32_INSTRUCTION_RNG] instruction_f; `endif output [`LM32_INSTRUCTION_RNG] instruction_d; // D stage instruction to be decoded reg [`LM32_INSTRUCTION_RNG] instruction_d; ///////////////////////////////////////////////////// // Internal nets and registers ///////////////////////////////////////////////////// reg [`LM32_PC_RNG] pc_a; // A stage PC `ifdef LM32_CACHE_ENABLED reg [`LM32_PC_RNG] restart_address; // Address to restart from after a cache miss `endif `ifdef CFG_ICACHE_ENABLED wire icache_read_enable_f; // Indicates if instruction cache miss is valid wire [`LM32_PC_RNG] icache_refill_address; // Address that caused cache miss reg icache_refill_ready; // Indicates when next word of refill data is ready to be written to cache reg [`LM32_INSTRUCTION_RNG] icache_refill_data; // Next word of refill data, fetched from Wishbone wire [`LM32_INSTRUCTION_RNG] icache_data_f; // Instruction fetched from instruction cache wire [`LM32_CTYPE_RNG] first_cycle_type; // First Wishbone cycle type wire [`LM32_CTYPE_RNG] next_cycle_type; // Next Wishbone cycle type wire last_word; // Indicates if this is the last word in the cache line wire [`LM32_PC_RNG] first_address; // First cache refill address `else `ifdef CFG_IWB_ENABLED reg [`LM32_INSTRUCTION_RNG] wb_data_f; // Instruction fetched from Wishbone `endif `endif `ifdef CFG_IROM_ENABLED wire irom_select_a; // Indicates if A stage PC maps to a ROM address reg irom_select_f; // Indicates if F stage PC maps to a ROM address wire [`LM32_INSTRUCTION_RNG] irom_data_f; // Instruction fetched from ROM `endif `ifdef CFG_EBR_POSEDGE_REGISTER_FILE `else wire [`LM32_INSTRUCTION_RNG] instruction_f; // F stage instruction `endif `ifdef CFG_BUS_ERRORS_ENABLED reg bus_error_f; // Indicates if a bus error occured while fetching the instruction in the F stage `endif `ifdef CFG_HW_DEBUG_ENABLED reg jtag_access; // Indicates if a JTAG WB access is in progress `endif `ifdef CFG_ALTERNATE_EBA reg alternate_eba_taken; `endif ///////////////////////////////////////////////////// // Functions ///////////////////////////////////////////////////// `include "lm32_functions.v" ///////////////////////////////////////////////////// // Instantiations ///////////////////////////////////////////////////// // Instruction ROM `ifdef CFG_IROM_ENABLED pmi_ram_dp_true #( // ----- Parameters ------- .pmi_family (`LATTICE_FAMILY), //.pmi_addr_depth_a (1 << (clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)), //.pmi_addr_width_a ((clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)), //.pmi_data_width_a (`LM32_WORD_WIDTH), //.pmi_addr_depth_b (1 << (clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)), //.pmi_addr_width_b ((clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)), //.pmi_data_width_b (`LM32_WORD_WIDTH), .pmi_addr_depth_a (`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1), .pmi_addr_width_a (clogb2_v1(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)), .pmi_data_width_a (`LM32_WORD_WIDTH), .pmi_addr_depth_b (`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1), .pmi_addr_width_b (clogb2_v1(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)), .pmi_data_width_b (`LM32_WORD_WIDTH), .pmi_regmode_a ("noreg"), .pmi_regmode_b ("noreg"), .pmi_gsr ("enable"), .pmi_resetmode ("sync"), .pmi_init_file (`CFG_IROM_INIT_FILE), .pmi_init_file_format (`CFG_IROM_INIT_FILE_FORMAT), .module_type ("pmi_ram_dp_true") ) ram ( // ----- Inputs ------- .ClockA (clk_i), .ClockB (clk_i), .ResetA (rst_i), .ResetB (rst_i), .DataInA ({32{1'b0}}), .DataInB (irom_store_data_m), .AddressA (pc_a[(clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)+2-1:2]), .AddressB (irom_address_xm[(clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)+2-1:2]), .ClockEnA (!stall_a), .ClockEnB (!stall_x || !stall_m), .WrA (`FALSE), .WrB (irom_we_xm), // ----- Outputs ------- .QA (irom_data_f), .QB (irom_data_m) ); `endif `ifdef CFG_ICACHE_ENABLED // Instruction cache lm32_icache #( .associativity (associativity), .sets (sets), .bytes_per_line (bytes_per_line), .base_address (base_address), .limit (limit) ) icache ( // ----- Inputs ----- .clk_i (clk_i), .rst_i (rst_i), .stall_a (stall_a), .stall_f (stall_f), .branch_predict_taken_d (branch_predict_taken_d), .valid_d (valid_d), .address_a (pc_a), .address_f (pc_f), .read_enable_f (icache_read_enable_f), .refill_ready (icache_refill_ready), .refill_data (icache_refill_data), .iflush (iflush), // ----- Outputs ----- .stall_request (icache_stall_request), .restart_request (icache_restart_request), .refill_request (icache_refill_request), .refill_address (icache_refill_address), .refilling (icache_refilling), .inst (icache_data_f) ); `endif ///////////////////////////////////////////////////// // Combinational Logic ///////////////////////////////////////////////////// `ifdef CFG_ICACHE_ENABLED // Generate signal that indicates when instruction cache misses are valid assign icache_read_enable_f = (valid_f == `TRUE) && (kill_f == `FALSE) `ifdef CFG_DCACHE_ENABLED && (dcache_restart_request == `FALSE) `endif `ifdef CFG_IROM_ENABLED && (irom_select_f == `FALSE) `endif ; `endif // Compute address of next instruction to fetch always @(*) begin // The request from the latest pipeline stage must take priority `ifdef CFG_DCACHE_ENABLED if (dcache_restart_request == `TRUE) pc_a = restart_address; else `endif if (branch_taken_m == `TRUE) if ((branch_mispredict_taken_m == `TRUE) && (exception_m == `FALSE)) pc_a = pc_x; else pc_a = branch_target_m; `ifdef CFG_FAST_UNCONDITIONAL_BRANCH else if (branch_taken_x == `TRUE) pc_a = branch_target_x; `endif else if ( (valid_d == `TRUE) && (branch_predict_taken_d == `TRUE) ) pc_a = branch_predict_address_d; else `ifdef CFG_ICACHE_ENABLED if (icache_restart_request == `TRUE) pc_a = restart_address; else `endif pc_a = pc_f + 1'b1; end // Select where instruction should be fetched from `ifdef CFG_IROM_ENABLED assign irom_select_a = ({pc_a, 2'b00} >= `CFG_IROM_BASE_ADDRESS) && ({pc_a, 2'b00} <= `CFG_IROM_LIMIT); `endif // Select instruction from selected source `ifdef CFG_ICACHE_ENABLED `ifdef CFG_IROM_ENABLED assign instruction_f = irom_select_f == `TRUE ? irom_data_f : icache_data_f; `else assign instruction_f = icache_data_f; `endif `else `ifdef CFG_IROM_ENABLED `ifdef CFG_IWB_ENABLED assign instruction_f = irom_select_f == `TRUE ? irom_data_f : wb_data_f; `else assign instruction_f = irom_data_f; `endif `else assign instruction_f = wb_data_f; `endif `endif // Unused/constant Wishbone signals `ifdef CFG_IWB_ENABLED `ifdef CFG_HW_DEBUG_ENABLED `else assign i_dat_o = 32'd0; assign i_we_o = `FALSE; assign i_sel_o = 4'b1111; `endif assign i_bte_o = `LM32_BTYPE_LINEAR; `endif `ifdef CFG_ICACHE_ENABLED // Determine parameters for next cache refill Wishbone access generate case (bytes_per_line) 4: begin assign first_cycle_type = `LM32_CTYPE_END; assign next_cycle_type = `LM32_CTYPE_END; assign last_word = `TRUE; assign first_address = icache_refill_address; end 8: begin assign first_cycle_type = `LM32_CTYPE_INCREMENTING; assign next_cycle_type = `LM32_CTYPE_END; assign last_word = i_adr_o[addr_offset_msb:addr_offset_lsb] == 1'b1; assign first_address = {icache_refill_address[`LM32_PC_WIDTH+2-1:addr_offset_msb+1], {addr_offset_width{1'b0}}}; end 16: begin assign first_cycle_type = `LM32_CTYPE_INCREMENTING; assign next_cycle_type = i_adr_o[addr_offset_msb] == 1'b1 ? `LM32_CTYPE_END : `LM32_CTYPE_INCREMENTING; assign last_word = i_adr_o[addr_offset_msb:addr_offset_lsb] == 2'b11; assign first_address = {icache_refill_address[`LM32_PC_WIDTH+2-1:addr_offset_msb+1], {addr_offset_width{1'b0}}}; end endcase endgenerate `endif ///////////////////////////////////////////////////// // Sequential Logic ///////////////////////////////////////////////////// // PC always @(posedge clk_i `CFG_RESET_SENSITIVITY) begin if (rst_i == `TRUE) begin `ifdef CFG_DEBUG_ENABLED `ifdef CFG_ALTERNATE_EBA if (at_debug == `TRUE) pc_f <= (`CFG_DEBA_RESET-4)/4; else pc_f <= (`CFG_EBA_RESET-4)/4; `else pc_f <= (`CFG_EBA_RESET-4)/4; `endif `else pc_f <= (`CFG_EBA_RESET-4)/4; `endif pc_d <= {`LM32_PC_WIDTH{1'b0}}; pc_x <= {`LM32_PC_WIDTH{1'b0}}; pc_m <= {`LM32_PC_WIDTH{1'b0}}; pc_w <= {`LM32_PC_WIDTH{1'b0}}; end else begin if (stall_f == `FALSE) pc_f <= pc_a; if (stall_d == `FALSE) pc_d <= pc_f; if (stall_x == `FALSE) pc_x <= pc_d; if (stall_m == `FALSE) pc_m <= pc_x; pc_w <= pc_m; end end `ifdef LM32_CACHE_ENABLED // Address to restart from after a cache miss has been handled always @(posedge clk_i `CFG_RESET_SENSITIVITY) begin if (rst_i == `TRUE) restart_address <= {`LM32_PC_WIDTH{1'b0}}; else begin `ifdef CFG_DCACHE_ENABLED `ifdef CFG_ICACHE_ENABLED // D-cache restart address must take priority, otherwise instructions will be lost if (dcache_refill_request == `TRUE) restart_address <= pc_w; else if ((icache_refill_request == `TRUE) && (!dcache_refilling) && (!dcache_restart_request)) restart_address <= icache_refill_address; `else if (dcache_refill_request == `TRUE) restart_address <= pc_w; `endif `else `ifdef CFG_ICACHE_ENABLED if (icache_refill_request == `TRUE) restart_address <= icache_refill_address; `endif `endif end end `endif // Record where instruction was fetched from `ifdef CFG_IROM_ENABLED always @(posedge clk_i `CFG_RESET_SENSITIVITY) begin if (rst_i == `TRUE) irom_select_f <= `FALSE; else begin if (stall_f == `FALSE) irom_select_f <= irom_select_a; end end `endif `ifdef CFG_HW_DEBUG_ENABLED assign jtag_access_complete = (i_cyc_o == `TRUE) && ((i_ack_i == `TRUE) || (i_err_i == `TRUE)) && (jtag_access == `TRUE); always @(*) begin case (jtag_address[1:0]) 2'b00: jtag_read_data = i_dat_i[`LM32_BYTE_3_RNG]; 2'b01: jtag_read_data = i_dat_i[`LM32_BYTE_2_RNG]; 2'b10: jtag_read_data = i_dat_i[`LM32_BYTE_1_RNG]; 2'b11: jtag_read_data = i_dat_i[`LM32_BYTE_0_RNG]; endcase end `endif `ifdef CFG_IWB_ENABLED // Instruction Wishbone interface `ifdef CFG_ICACHE_ENABLED always @(posedge clk_i `CFG_RESET_SENSITIVITY) begin if (rst_i == `TRUE) begin i_cyc_o <= `FALSE; i_stb_o <= `FALSE; i_adr_o <= {`LM32_WORD_WIDTH{1'b0}}; i_cti_o <= `LM32_CTYPE_END; i_lock_o <= `FALSE; icache_refill_data <= {`LM32_INSTRUCTION_WIDTH{1'b0}}; icache_refill_ready <= `FALSE; `ifdef CFG_BUS_ERRORS_ENABLED bus_error_f <= `FALSE; `endif `ifdef CFG_HW_DEBUG_ENABLED i_we_o <= `FALSE; i_sel_o <= 4'b1111; jtag_access <= `FALSE; `endif end else begin icache_refill_ready <= `FALSE; // Is a cycle in progress? if (i_cyc_o == `TRUE) begin // Has cycle completed? if ((i_ack_i == `TRUE) || (i_err_i == `TRUE)) begin `ifdef CFG_HW_DEBUG_ENABLED if (jtag_access == `TRUE) begin i_cyc_o <= `FALSE; i_stb_o <= `FALSE; i_we_o <= `FALSE; jtag_access <= `FALSE; end else `endif begin if (last_word == `TRUE) begin // Cache line fill complete i_cyc_o <= `FALSE; i_stb_o <= `FALSE; i_lock_o <= `FALSE; end // Fetch next word in cache line i_adr_o[addr_offset_msb:addr_offset_lsb] <= i_adr_o[addr_offset_msb:addr_offset_lsb] + 1'b1; i_cti_o <= next_cycle_type; // Write fetched data into instruction cache icache_refill_ready <= `TRUE; icache_refill_data <= i_dat_i; end end `ifdef CFG_BUS_ERRORS_ENABLED if (i_err_i == `TRUE) begin bus_error_f <= `TRUE; $display ("Instruction bus error. Address: %x", i_adr_o); end `endif end else begin if ((icache_refill_request == `TRUE) && (icache_refill_ready == `FALSE)) begin // Read first word of cache line `ifdef CFG_HW_DEBUG_ENABLED i_sel_o <= 4'b1111; `endif i_adr_o <= {first_address, 2'b00}; i_cyc_o <= `TRUE; i_stb_o <= `TRUE; i_cti_o <= first_cycle_type; //i_lock_o <= `TRUE; `ifdef CFG_BUS_ERRORS_ENABLED bus_error_f <= `FALSE; `endif end `ifdef CFG_HW_DEBUG_ENABLED else begin if ((jtag_read_enable == `TRUE) || (jtag_write_enable == `TRUE)) begin case (jtag_address[1:0]) 2'b00: i_sel_o <= 4'b1000; 2'b01: i_sel_o <= 4'b0100; 2'b10: i_sel_o <= 4'b0010; 2'b11: i_sel_o <= 4'b0001; endcase i_adr_o <= jtag_address; i_dat_o <= {4{jtag_write_data}}; i_cyc_o <= `TRUE; i_stb_o <= `TRUE; i_we_o <= jtag_write_enable; i_cti_o <= `LM32_CTYPE_END; jtag_access <= `TRUE; end end `endif `ifdef CFG_BUS_ERRORS_ENABLED // Clear bus error when exception taken, otherwise they would be // continually generated if exception handler is cached `ifdef CFG_FAST_UNCONDITIONAL_BRANCH if (branch_taken_x == `TRUE) bus_error_f <= `FALSE; `endif if (branch_taken_m == `TRUE) bus_error_f <= `FALSE; `endif end end end `else always @(posedge clk_i `CFG_RESET_SENSITIVITY) begin if (rst_i == `TRUE) begin i_cyc_o <= `FALSE; i_stb_o <= `FALSE; i_adr_o <= {`LM32_WORD_WIDTH{1'b0}}; i_cti_o <= `LM32_CTYPE_END; i_lock_o <= `FALSE; wb_data_f <= {`LM32_INSTRUCTION_WIDTH{1'b0}}; `ifdef CFG_BUS_ERRORS_ENABLED bus_error_f <= `FALSE; `endif end else begin // Is a cycle in progress? if (i_cyc_o == `TRUE) begin // Has cycle completed? if((i_ack_i == `TRUE) || (i_err_i == `TRUE)) begin // Cycle complete i_cyc_o <= `FALSE; i_stb_o <= `FALSE; // Register fetched instruction wb_data_f <= i_dat_i; end `ifdef CFG_BUS_ERRORS_ENABLED if (i_err_i == `TRUE) begin bus_error_f <= `TRUE; $display ("Instruction bus error. Address: %x", i_adr_o); end `endif end else begin // Wait for an instruction fetch from an external address if ( (stall_a == `FALSE) `ifdef CFG_IROM_ENABLED && (irom_select_a == `FALSE) `endif ) begin // Fetch instruction `ifdef CFG_HW_DEBUG_ENABLED i_sel_o <= 4'b1111; `endif i_adr_o <= {pc_a, 2'b00}; i_cyc_o <= `TRUE; i_stb_o <= `TRUE; `ifdef CFG_BUS_ERRORS_ENABLED bus_error_f <= `FALSE; `endif end else begin if ( (stall_a == `FALSE) `ifdef CFG_IROM_ENABLED && (irom_select_a == `TRUE) `endif ) begin `ifdef CFG_BUS_ERRORS_ENABLED bus_error_f <= `FALSE; `endif end end end end end `endif `endif // Instruction register always @(posedge clk_i `CFG_RESET_SENSITIVITY) begin if (rst_i == `TRUE) begin instruction_d <= {`LM32_INSTRUCTION_WIDTH{1'b0}}; `ifdef CFG_BUS_ERRORS_ENABLED bus_error_d <= `FALSE; `endif end else begin if (stall_d == `FALSE) begin instruction_d <= instruction_f; `ifdef CFG_BUS_ERRORS_ENABLED bus_error_d <= bus_error_f; `endif end end end endmodule