URL
https://opencores.org/ocsvn/claw/claw/trunk
Subversion Repositories claw
[/] [claw/] [trunk/] [or1200_cpu/] [or1200_if.v] - Rev 4
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 //// //// Updated by: //// //// - Balaji V. Iyer, bviyer@ncsu.edu //// //// Advisor: //// //// - Dr. Tom Conte //// //// //// ////////////////////////////////////////////////////////////////////// //// //// //// 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: not supported by cvs2svn $ // 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_insn2, if_pc, flushpipe, if_stall, no_more_dslot, genpc_refetch, rfe, except_itlbmiss, except_immufault, except_ibuserr, thread_in, thread_out ); // // I/O // // // Clock and reset // input clk; input rst; // // External i/f to IC // // bviyer: changed the size ofhte bus from 32 to 64 input [63: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_insn2; // by bviyer. output [31:0] if_pc; input flushpipe; output if_stall; input no_more_dslot; output genpc_refetch; input rfe; output except_itlbmiss; output except_immufault; output except_ibuserr; input [2:0] thread_in; output[2:0] thread_out; // // Internal wires and regs // reg [31:0] insn_saved; // added by bviyer: this wil be use to save an additional instruction reg [31:0] insn_saved2; reg [31:0] addr_saved; reg saved; // // IF stage insn // assign if_insn = icpu_err_i | no_more_dslot | rfe ? {`OR1200_OR32_NOP, 26'h041_0000} : saved ? insn_saved : icpu_ack_i ? icpu_dat_i[31:0] : {`OR1200_OR32_NOP, 26'h061_0000}; // added by bviyer: used to supply an additional instrucion assign if_insn2 = icpu_err_i | no_more_dslot | rfe ? {`OR1200_OR32_NOP, 26'h041_0000} : saved ? insn_saved2 : icpu_ack_i ? icpu_dat_i[63:32] : {`OR1200_OR32_NOP, 26'h061_0000}; assign if_pc = saved ? addr_saved : icpu_adr_i; // assign if_stall = !icpu_err_i & !icpu_ack_i & !saved & !no_more_dslot; assign if_stall = !icpu_err_i & !icpu_ack_i & !saved; assign genpc_refetch = saved & icpu_ack_i; assign except_itlbmiss = icpu_err_i & (icpu_tag_i == `OR1200_ITAG_TE) & !no_more_dslot; assign except_immufault = icpu_err_i & (icpu_tag_i == `OR1200_ITAG_PE) & !no_more_dslot; assign except_ibuserr = icpu_err_i & (icpu_tag_i == `OR1200_ITAG_BE) & !no_more_dslot; // // Flag for saved insn/address // always @(posedge clk or posedge rst) if (rst) saved <= 1'b0; else if (flushpipe) saved <= 1'b0; else if (icpu_ack_i & if_freeze & !saved) saved <= 1'b1; else if (!if_freeze) saved <= 1'b0; // // Store fetched instruction // // added by bviyer: the additional insn_saved register to hold the saved NOp or the data always @(posedge clk or posedge rst) if (rst) insn_saved <= {`OR1200_OR32_NOP, 26'h041_0000}; else if (flushpipe) insn_saved <= {`OR1200_OR32_NOP, 26'h041_0000}; else if (icpu_ack_i & if_freeze & !saved) insn_saved <= icpu_dat_i[31:0]; else if (!if_freeze) insn_saved <= {`OR1200_OR32_NOP, 26'h041_0000}; // // Store fetched instruction's address // always @(posedge clk or posedge rst) if (rst) insn_saved2 <= {`OR1200_OR32_NOP, 26'h041_0000}; else if (flushpipe) insn_saved2 <= {`OR1200_OR32_NOP, 26'h041_0000}; else if (icpu_ack_i & if_freeze & !saved) insn_saved2 <= icpu_dat_i[63:32]; else if (!if_freeze) insn_saved2 <= {`OR1200_OR32_NOP, 26'h041_0000}; always @(posedge clk or posedge rst) if (rst) addr_saved <= 32'h00000000; else if (flushpipe) addr_saved <= 32'h00000000; else if (icpu_ack_i & if_freeze & !saved) addr_saved <= icpu_adr_i; else if (!if_freeze) addr_saved <= icpu_adr_i; assign thread_out = thread_in; endmodule