URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [branches/] [mp3_stable/] [mp3/] [rtl/] [verilog/] [or1200.xcv/] [ic.v] - Rev 1765
Compare with Previous | Blame | View Log
////////////////////////////////////////////////////////////////////// //// //// //// OR1200's Instruction Cache Top Level //// //// //// //// This file is part of the OpenRISC 1200 project //// //// http://www.opencores.org/cores/or1k/ //// //// //// //// Description //// //// Instruction cache top level instantiating all IC blocks. //// //// //// //// 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: not supported by cvs2svn $ // Revision 1.1.1.1 2001/10/06 10:18:36 igorm // no message // // Revision 1.4 2001/08/17 08:01:19 lampret // IC enable/disable. // // Revision 1.3 2001/08/13 03:36:20 lampret // Added cfg regs. Moved all defines into one defines.v file. More cleanup. // // Revision 1.2 2001/08/09 13:39:33 lampret // Major clean-up. // // Revision 1.1 2001/07/20 00:46:03 lampret // Development version of RTL. Libraries are missing. // // // synopsys translate_off `include "timescale.v" // synopsys translate_on `include "defines.v" module ic( clk, rst, clkdiv_by_2, // Internal i/f to fetcher ic_en, icfetch_dataout, icfetch_addr, icfetch_op, icfetch_stall, // SPRs spr_cs, spr_write, spr_addr, spr_dat_i, // External i/f to BIU icbiu_rdy, icbiu_addr, icbiu_read, icbiu_datain, icbiu_sel ); parameter dw = `OPERAND_WIDTH; // // I/O // // // Clock and reset // input clk; input rst; input clkdiv_by_2; // // External I/F // input icbiu_rdy; output [31:0] icbiu_addr; output icbiu_read; input [dw-1:0] icbiu_datain; output [3:0] icbiu_sel; // // Internal I/F // input ic_en; output [dw-1:0] icfetch_dataout; input [31:0] icfetch_addr; input [`FETCHOP_WIDTH-1:0] icfetch_op; output icfetch_stall; // // SPR access // input spr_cs; input spr_write; input [31:0] spr_addr; input [31:0] spr_dat_i; // // Internal wires and regs // wire tag_v; wire [18:0] tag; wire [dw-1:0] to_icram; wire [dw-1:0] from_icram; wire [31:0] saved_addr; wire refill; wire [3:0] icram_we; wire ictag_we; wire [31:0] ic_addr; wire refill_first; wire refill_prepare; wire refill_start; wire refill_rest; reg [1:0] valid_div; reg hit; wire queue; wire cntrbusy; wire icbiu_valid; wire [`FETCHOP_WIDTH-1:0] icfsm_op; wire icfsm_read; reg [1:0] bypass_wait; wire [`ICINDXH:4] ictag_addr; wire ictag_en; wire ictag_v; wire ic_inv; // // Simple assignments // assign ic_inv = spr_cs & spr_write; assign icbiu_addr = ic_addr; assign ictag_we = refill | ic_inv; assign ictag_addr = ic_inv ? spr_dat_i[`ICINDXH:4] : ic_addr[`ICINDXH:4]; assign ictag_en = ic_inv | ic_en; assign ictag_v = ~ic_inv; // // Bypass of IC when it is disabled // assign icfsm_op = (ic_en) ? icfetch_op : `FETCHOP_NOP; assign icbiu_read = (ic_en) ? icfsm_read : (icfetch_op != `FETCHOP_NOP); assign icbiu_sel = 4'b1111; // // Wait for IC bypass access // always @(posedge rst or posedge clk) if (rst) bypass_wait <= #1 2'b0; // else if (icbiu_valid) else if (icbiu_rdy) bypass_wait <= #1 2'b0; else if (icbiu_read) bypass_wait <= #1 {bypass_wait[0], 1'b1}; else bypass_wait <= #1 2'b00; // // Queue // assign queue = (refill && icfsm_op && !refill_first & !refill_rest) ? 1'b1 : 1'b0; // // IC fetch stall // //assign icfetch_stall = (ic_en & (refill | ~hit)) | (~ic_en & bypass_wait[1] & ~icbiu_valid); //assign icfetch_stall = (ic_en & (refill | ~hit)) | (~ic_en & bypass_wait[1] & ~icbiu_rdy); assign icfetch_stall = (ic_en & (refill | ~hit)) | (~ic_en & icbiu_read & ~icbiu_rdy); // // Select between claddr generated by IC FSM and addr[3:2] generated by IFETCH // assign ic_addr = (refill == 1'b1) ? saved_addr : icfetch_addr; // // Input data generated by BIU // assign to_icram = icbiu_datain; // // Select between data generated by ICRAM or passed by BIU // assign icfetch_dataout = (refill_first == 1'b1) | (~ic_en) ? icbiu_datain : from_icram; // // Tag comparison // always @(tag or saved_addr or tag_v) begin if ((tag == saved_addr[31:`ICTAGL]) && tag_v) hit = 1'b1; else hit = 1'b0; end // // Valid_div counts RISC clock cycles by modulo 4 // always @(posedge clk or posedge rst) if (rst) valid_div <= #1 2'b0; else valid_div <= #1 valid_div + 'd1; // // icbiu_valid is one RISC clock cycle long icbiu_rdy. // icbiu_rdy is two/four RISC clock cycles long because memory // controller works at 1/2 or 1/4 of RISC clock freq (at 1/2 if // clkdiv_by_2 is asserted). // assign icbiu_valid = icbiu_rdy & (valid_div[1] | clkdiv_by_2) & valid_div[0]; // // Generate refill_start that signals to frz_logic a cache linefill is about to begin // assign refill_start = (refill_prepare & ~hit) ? 1'b1 : 1'b0; // // Instantiation of IC FSM // ic_fsm ic_fsm( .clk(clk), .rst(rst), .fetch_op(icfsm_op), .miss(~hit), .biudata_valid(icbiu_valid), .start_addr(icfetch_addr), .saved_addr(saved_addr), .refill(refill), .refill_first(refill_first), .refill_prepare(refill_prepare), .icram_we(icram_we), .biu_read(icfsm_read), .refill_rest(refill_rest), .cntrbusy(cntrbusy) ); // // Instantiation of IC main memory // ic_ram ic_ram( .clk(clk), .rst(rst), .addr(ic_addr[`ICINDXH:2]), .en(ic_en), .we(icram_we), .datain(to_icram), .dataout(from_icram) ); // // Instantiation of IC TAG memory // ic_tag ic_tag( .clk(clk), .rst(rst), .addr(ictag_addr[`ICINDXH:4]), .en(ictag_en), .we(ictag_we), .datain({ic_addr[31:`ICTAGL], ictag_v}), .tag_v(tag_v), .tag(tag) ); endmodule