URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [or1200/] [rtl/] [verilog/] [or1200_if.v] - Rev 216
Go to most recent revision | Compare with Previous | Blame | View Log
////////////////////////////////////////////////////////////////////// //// //// //// OR1200's instruction fetch //// //// //// //// This file is part of the OpenRISC 1200 project //// //// http://www.opencores.org/cores/or1k/ //// //// //// //// Description //// //// PC, instruction fetch, interface to IC. //// //// //// //// To Do: //// //// - make it smaller and faster //// //// //// //// Author(s): //// //// - Damjan Lampret, lampret@opencores.org //// //// //// ////////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2000 Authors and OPENCORES.ORG //// //// //// //// This source file may be used and distributed without //// //// restriction provided that this copyright statement is not //// //// removed from the file and that any derivative work contains //// //// the original copyright notice and the associated disclaimer. //// //// //// //// This source file is free software; you can redistribute it //// //// and/or modify it under the terms of the GNU Lesser General //// //// Public License as published by the Free Software Foundation; //// //// either version 2.1 of the License, or (at your option) any //// //// later version. //// //// //// //// This source is distributed in the hope that it will be //// //// useful, but WITHOUT ANY WARRANTY; without even the implied //// //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// //// PURPOSE. See the GNU Lesser General Public License for more //// //// details. //// //// //// //// You should have received a copy of the GNU Lesser General //// //// Public License along with this source; if not, download it //// //// from http://www.opencores.org/lgpl.shtml //// //// //// ////////////////////////////////////////////////////////////////////// // // CVS Revision History // // $Log: or1200_if.v,v $ // Revision 2.0 2010/06/30 11:00:00 ORSoC // Major update: // Structure reordered and bugs fixed. // // Revision 1.5 2004/04/05 08:29:57 lampret // Merged branch_qmem into main tree. // // Revision 1.3 2002/03/29 15:16:56 lampret // Some of the warnings fixed. // // Revision 1.2 2002/01/28 01:16:00 lampret // Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways. // // Revision 1.1 2002/01/03 08:16:15 lampret // New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs. // // Revision 1.10 2001/11/20 18:46:15 simons // Break point bug fixed // // Revision 1.9 2001/11/18 09:58:28 lampret // Fixed some l.trap typos. // // Revision 1.8 2001/11/18 08:36:28 lampret // For GDB changed single stepping and disabled trap exception. // // Revision 1.7 2001/10/21 17:57:16 lampret // Removed params from generic_XX.v. Added translate_off/on in sprs.v and id.v. Removed spr_addr from dc.v and ic.v. Fixed CR+LF. // // Revision 1.6 2001/10/14 13:12:09 lampret // MP3 version. // // Revision 1.1.1.1 2001/10/06 10:18:36 igorm // no message // // Revision 1.1 2001/08/09 13:39:33 lampret // Major clean-up. // // // synopsys translate_off `include "timescale.v" // synopsys translate_on `include "or1200_defines.v" module or1200_if( // Clock and reset clk, rst, // External i/f to IC icpu_dat_i, icpu_ack_i, icpu_err_i, icpu_adr_i, icpu_tag_i, // Internal i/f if_freeze, if_insn, if_pc, if_flushpipe, saving_if_insn, if_stall, no_more_dslot, genpc_refetch, rfe, except_itlbmiss, except_immufault, except_ibuserr ); // // I/O // // // Clock and reset // input clk; input rst; // // External i/f to IC // input [31:0] icpu_dat_i; input icpu_ack_i; input icpu_err_i; input [31:0] icpu_adr_i; input [3:0] icpu_tag_i; // // Internal i/f // input if_freeze; output [31:0] if_insn; output [31:0] if_pc; input if_flushpipe; output saving_if_insn; output if_stall; input no_more_dslot; output genpc_refetch; input rfe; output except_itlbmiss; output except_immufault; output except_ibuserr; // // Internal wires and regs // wire save_insn; wire if_bypass; reg if_bypass_reg; reg [31:0] insn_saved; reg [31:0] addr_saved; reg [2:0] err_saved; reg saved; assign save_insn = (icpu_ack_i | icpu_err_i) & if_freeze & !saved; assign saving_if_insn = !if_flushpipe & save_insn; // // IF bypass // assign if_bypass = icpu_adr_i[0] ? 1'b0 : if_bypass_reg | if_flushpipe; always @(posedge clk or posedge rst) if (rst) if_bypass_reg <= #1 1'b0; else if_bypass_reg <= #1 if_bypass; // // IF stage insn // assign if_insn = no_more_dslot | rfe | if_bypass ? {`OR1200_OR32_NOP, 26'h041_0000} : saved ? insn_saved : icpu_ack_i ? icpu_dat_i : {`OR1200_OR32_NOP, 26'h061_0000}; assign if_pc = saved ? addr_saved : {icpu_adr_i[31:2], 2'h0}; assign if_stall = !icpu_err_i & !icpu_ack_i & !saved; assign genpc_refetch = saved & icpu_ack_i; assign except_itlbmiss = no_more_dslot ? 1'b0 : saved ? err_saved[0] : icpu_err_i & (icpu_tag_i == `OR1200_ITAG_TE); assign except_immufault = no_more_dslot ? 1'b0 : saved ? err_saved[1] : icpu_err_i & (icpu_tag_i == `OR1200_ITAG_PE); assign except_ibuserr = no_more_dslot ? 1'b0 : saved ? err_saved[2] : icpu_err_i & (icpu_tag_i == `OR1200_ITAG_BE); // // Flag for saved insn/address // always @(posedge clk or posedge rst) if (rst) saved <= #1 1'b0; else if (if_flushpipe) saved <= #1 1'b0; else if (save_insn) saved <= #1 1'b1; else if (!if_freeze) saved <= #1 1'b0; // // Store fetched instruction // always @(posedge clk or posedge rst) if (rst) insn_saved <= #1 {`OR1200_OR32_NOP, 26'h041_0000}; else if (if_flushpipe) insn_saved <= #1 {`OR1200_OR32_NOP, 26'h041_0000}; else if (save_insn) insn_saved <= #1 icpu_err_i ? {`OR1200_OR32_NOP, 26'h041_0000} : icpu_dat_i; else if (!if_freeze) insn_saved <= #1 {`OR1200_OR32_NOP, 26'h041_0000}; // // Store fetched instruction's address // always @(posedge clk or posedge rst) if (rst) addr_saved <= #1 32'h00000000; else if (if_flushpipe) addr_saved <= #1 32'h00000000; else if (save_insn) addr_saved <= #1 {icpu_adr_i[31:2], 2'b00}; else if (!if_freeze) addr_saved <= #1 {icpu_adr_i[31:2], 2'b00}; // // Store fetched instruction's error tags // always @(posedge clk or posedge rst) if (rst) err_saved <= #1 3'b000; else if (if_flushpipe) err_saved <= #1 3'b000; else if (save_insn) begin err_saved[0] <= #1 icpu_err_i & (icpu_tag_i == `OR1200_ITAG_TE); err_saved[1] <= #1 icpu_err_i & (icpu_tag_i == `OR1200_ITAG_PE); err_saved[2] <= #1 icpu_err_i & (icpu_tag_i == `OR1200_ITAG_BE); end else if (!if_freeze) err_saved <= #1 3'b000; endmodule
Go to most recent revision | Compare with Previous | Blame | View Log