HierarchyFilesModulesSignalsTasksFunctionsHelp
12

/******************************************************************************/ 
/*                                                                            */ 
/* Copyright (c) 1999 Sun Microsystems, Inc. All rights reserved.             */ 
/*                                                                            */ 
/* The contents of this file are subject to the current version of the Sun    */ 
/* Community Source License, microSPARCII ("the License"). You may not use    */ 
/* this file except in compliance with the License.  You may obtain a copy    */ 
/* of the License by searching for "Sun Community Source License" on the      */ 
/* World Wide Web at http://www.sun.com. See the License for the rights,      */ 
/* obligations, and limitations governing use of the contents of this file.   */ 
/*                                                                            */ 
/* Sun Microsystems, Inc. has intellectual property rights relating to the    */ 
/* technology embodied in these files. In particular, and without limitation, */ 
/* these intellectual property rights may include one or more U.S. patents,   */ 
/* foreign patents, or pending applications.                                  */ 
/*                                                                            */ 
/* Sun, Sun Microsystems, the Sun logo, all Sun-based trademarks and logos,   */ 
/* Solaris, Java and all Java-based trademarks and logos are trademarks or    */ 
/* registered trademarks of Sun Microsystems, Inc. in the United States and   */ 
/* other countries. microSPARC is a trademark or registered trademark of      */ 
/* SPARC International, Inc. All SPARC trademarks are used under license and  */ 
/* are trademarks or registered trademarks of SPARC International, Inc. in    */ 
/* the United States and other countries. Products bearing SPARC trademarks   */ 
/* are based upon an architecture developed by Sun Microsystems, Inc.         */ 
/*                                                                            */ 
/******************************************************************************/ 
//***************************************************************************
// mc_e_tlb.v
//
//
// Description :
//    RTL level for TLB megecell emulation
//
// Created:     11/12/91
//
//****************************************************************************

[Up: afxmaster io_tlb]
module IOTLB (RD_OUT27,RD_OUT26,RD_OUT25,RD_OUT24,RD_OUT23,RD_OUT22,RD_OUT21,RD_OUT20,RD_OUT19,RD_OUT18,RD_OUT17,RD_OUT16,RD_OUT15,RD_OUT14,RD_OUT13,RD_OUT12,RD_OUT11,RD_OUT10,RD_OUT9,RD_OUT8,RD_OUT7,RD_OUT6,RD_OUT5,RD_OUT4,RD_OUT3,RD_OUT2,RD_OUT1,RD_OUT0,
CD_OUT41,CD_OUT40,CD_OUT39,CD_OUT38,CD_OUT37,CD_OUT36,CD_OUT35,CD_OUT34,CD_OUT33,CD_OUT32,CD_OUT31,CD_OUT30,CD_OUT29,CD_OUT28,CD_OUT27,CD_OUT26,CD_OUT25,CD_OUT24,CD_OUT23,CD_OUT22,CD_OUT21,CD_OUT20,CD_OUT19,CD_OUT18,CD_OUT17,CD_OUT16,CD_OUT15,CD_OUT14,CD_OUT13,CD_OUT12,CD_OUT11,CD_OUT10,CD_OUT9,CD_OUT8,CD_OUT7,CD_OUT6,CD_OUT5,CD_OUT4,CD_OUT3,CD_OUT2,CD_OUT1,CD_OUT0,
MISS,
ACC_OK,
ERROR,
M_MISS,
RD_IN27,RD_IN26,RD_IN25,RD_IN24,RD_IN23,RD_IN22,RD_IN21,RD_IN20,RD_IN19,RD_IN18,RD_IN17,RD_IN16,RD_IN15,RD_IN14,RD_IN13,RD_IN12,RD_IN11,RD_IN10,RD_IN9,RD_IN8,RD_IN7,RD_IN6,RD_IN5,RD_IN4,RD_IN3,RD_IN2,RD_IN1,RD_IN0,
CD_IN41,CD_IN40,CD_IN39,CD_IN38,CD_IN37,CD_IN36,CD_IN35,CD_IN34,CD_IN33,CD_IN32,CD_IN31,CD_IN30,CD_IN29,CD_IN28,CD_IN27,CD_IN26,CD_IN25,CD_IN24,CD_IN23,CD_IN22,CD_IN21,CD_IN20,CD_IN19,CD_IN18,CD_IN17,CD_IN16,CD_IN15,CD_IN14,CD_IN13,CD_IN12,CD_IN11,CD_IN10,CD_IN9,CD_IN8,CD_IN7,CD_IN6,CD_IN5,CD_IN4,CD_IN3,CD_IN2,CD_IN1,CD_IN0,
FLUSH,
TLB_WE,
ASEL,
ADDR3,ADDR2,ADDR1,ADDR0,
CO_IN,
CR,
CLK,
RST);

// SCM,
// SCN_IN,
// TG_STROBE,
// SCN_OUT,
// PDM,


input RD_IN27,RD_IN26,RD_IN25,RD_IN24,RD_IN23,RD_IN22,RD_IN21,RD_IN20,RD_IN19,RD_IN18,RD_IN17,RD_IN16,RD_IN15,RD_IN14,RD_IN13,RD_IN12,RD_IN11,RD_IN10,RD_IN9,RD_IN8,RD_IN7,RD_IN6,RD_IN5,RD_IN4,RD_IN3,RD_IN2,RD_IN1,RD_IN0,
CD_IN41,CD_IN40,CD_IN39,CD_IN38,CD_IN37,CD_IN36,CD_IN35,CD_IN34,CD_IN33,CD_IN32,CD_IN31,CD_IN30,CD_IN29,CD_IN28,CD_IN27,CD_IN26,CD_IN25,CD_IN24,CD_IN23,CD_IN22,CD_IN21,CD_IN20,CD_IN19,CD_IN18,CD_IN17,CD_IN16,CD_IN15,CD_IN14,CD_IN13,CD_IN12,CD_IN11,CD_IN10,CD_IN9,CD_IN8,CD_IN7,CD_IN6,CD_IN5,CD_IN4,CD_IN3,CD_IN2,CD_IN1,CD_IN0,
FLUSH,
TLB_WE,
ASEL,
ADDR3,ADDR2,ADDR1,ADDR0,
CO_IN,
CR,
CLK,
RST;
 
output RD_OUT27,RD_OUT26,RD_OUT25,RD_OUT24,RD_OUT23,RD_OUT22,RD_OUT21,RD_OUT20,RD_OUT19,RD_OUT18,RD_OUT17,RD_OUT16,RD_OUT15,RD_OUT14,RD_OUT13,RD_OUT12,RD_OUT11,RD_OUT10,RD_OUT9,RD_OUT8,RD_OUT7,RD_OUT6,RD_OUT5,RD_OUT4,RD_OUT3,RD_OUT2,RD_OUT1,RD_OUT0,
CD_OUT41,CD_OUT40,CD_OUT39,CD_OUT38,CD_OUT37,CD_OUT36,CD_OUT35,CD_OUT34,CD_OUT33,CD_OUT32,CD_OUT31,CD_OUT30,CD_OUT29,CD_OUT28,CD_OUT27,CD_OUT26,CD_OUT25,CD_OUT24,CD_OUT23,CD_OUT22,CD_OUT21,CD_OUT20,CD_OUT19,CD_OUT18,CD_OUT17,CD_OUT16,CD_OUT15,CD_OUT14,CD_OUT13,CD_OUT12,CD_OUT11,CD_OUT10,CD_OUT9,CD_OUT8,CD_OUT7,CD_OUT6,CD_OUT5,CD_OUT4,CD_OUT3,CD_OUT2,CD_OUT1,CD_OUT0,
MISS,
ACC_OK,
ERROR,
M_MISS;

// SCM,
// SCN_IN,
// TG_STROBE,
// PDM,
// SCN_OUT;

/********************* internal wiring definition ***********************/

wire [27:0]	rd_out;         // TLB RAM output
wire [41:0]	cd_out;         // TLB CAM output

wire 	 	miss;           // TLB miss output (based on match op)
wire 		acc_ok;         // protection & modified bits OK & ~miss
wire 		error;          // protection check failed & ~miss

wire		m_miss;         // modified bit from CAM
wire 		scn_out;        // Scan output of internal registers


wire [27:0] 	rd_in;          // RAM data input
wire [41:0] 	cd_in;          // CAM data input

wire 		flush;          // flush control input
wire 		tlb_we;         // RAM and CAM write enable

wire 		asel;           // Address select (1 means use addr)
wire [3:0] 	addr;           // 4-bit address for writes and reads

wire 		co_in;          // Compare override for IO and PTP bits
wire 		cr;             // CAM direct address read control input

wire 		scm;            // Scan mode control input
wire 		scn_in;         // Scan input for internal registers
wire 		tg_strobe;      // Test generation strobe (for scan ops)

wire 		clk;            // Clock for internal registers
wire 		pdm;
wire 		rst;           // Reset for internal registers

//-----------------------------------------------------------------------

assign RD_OUT27 = rd_out[27];
assign RD_OUT26 = rd_out[26];
assign RD_OUT25 = rd_out[25];
assign RD_OUT24 = rd_out[24];
assign RD_OUT23 = rd_out[23];
assign RD_OUT22 = rd_out[22];
assign RD_OUT21 = rd_out[21];
assign RD_OUT20 = rd_out[20];
assign RD_OUT19 = rd_out[19];
assign RD_OUT18 = rd_out[18];
assign RD_OUT17 = rd_out[17];
assign RD_OUT16 = rd_out[16];
assign RD_OUT15 = rd_out[15];
assign RD_OUT14 = rd_out[14];
assign RD_OUT13 = rd_out[13];
assign RD_OUT12 = rd_out[12];
assign RD_OUT11 = rd_out[11];
assign RD_OUT10 = rd_out[10];
assign RD_OUT9 = rd_out[9];
assign RD_OUT8 = rd_out[8];
assign RD_OUT7 = rd_out[7];
assign RD_OUT6 = rd_out[6];
assign RD_OUT5 = rd_out[5];
assign RD_OUT4 = rd_out[4];
assign RD_OUT3 = rd_out[3];
assign RD_OUT2 = rd_out[2];
assign RD_OUT1 = rd_out[1];
assign RD_OUT0 = rd_out[0];

assign CD_OUT41 = cd_out[41];
assign CD_OUT40 = cd_out[40];
assign CD_OUT39 = cd_out[39];
assign CD_OUT38 = cd_out[38];
assign CD_OUT37 = cd_out[37];
assign CD_OUT36 = cd_out[36];
assign CD_OUT35 = cd_out[35];
assign CD_OUT34 = cd_out[34];
assign CD_OUT33 = cd_out[33];
assign CD_OUT32 = cd_out[32];
assign CD_OUT31 = cd_out[31];
assign CD_OUT30 = cd_out[30];
assign CD_OUT29 = cd_out[29];
assign CD_OUT28 = cd_out[28];
assign CD_OUT27 = cd_out[27];
assign CD_OUT26 = cd_out[26];
assign CD_OUT25 = cd_out[25];
assign CD_OUT24 = cd_out[24];
assign CD_OUT23 = cd_out[23];
assign CD_OUT22 = cd_out[22];
assign CD_OUT21 = cd_out[21];
assign CD_OUT20 = cd_out[20];
assign CD_OUT19 = cd_out[19];
assign CD_OUT18 = cd_out[18];
assign CD_OUT17 = cd_out[17];
assign CD_OUT16 = cd_out[16];
assign CD_OUT15 = cd_out[15];
assign CD_OUT14 = cd_out[14];
assign CD_OUT13 = cd_out[13];
assign CD_OUT12 = cd_out[12];
assign CD_OUT11 = cd_out[11];
assign CD_OUT10 = cd_out[10];
assign CD_OUT9 = cd_out[9];
assign CD_OUT8 = cd_out[8];
assign CD_OUT7 = cd_out[7];
assign CD_OUT6 = cd_out[6];
assign CD_OUT5 = cd_out[5];
assign CD_OUT4 = cd_out[4];
assign CD_OUT3 = cd_out[3];
assign CD_OUT2 = cd_out[2];
assign CD_OUT1 = cd_out[1];
assign CD_OUT0 = cd_out[0];

assign MISS = miss;
assign ACC_OK = acc_ok;
assign ERROR = error;

assign M_MISS = m_miss;


assign rd_in[27] = RD_IN27;
assign rd_in[26] = RD_IN26;
assign rd_in[25] = RD_IN25;
assign rd_in[24] = RD_IN24;
assign rd_in[23] = RD_IN23;
assign rd_in[22] = RD_IN22;
assign rd_in[21] = RD_IN21;
assign rd_in[20] = RD_IN20;
assign rd_in[19] = RD_IN19;
assign rd_in[18] = RD_IN18;
assign rd_in[17] = RD_IN17;
assign rd_in[16] = RD_IN16;
assign rd_in[15] = RD_IN15;
assign rd_in[14] = RD_IN14;
assign rd_in[13] = RD_IN13;
assign rd_in[12] = RD_IN12;
assign rd_in[11] = RD_IN11;
assign rd_in[10] = RD_IN10;
assign rd_in[9] = RD_IN9;
assign rd_in[8] = RD_IN8;
assign rd_in[7] = RD_IN7;
assign rd_in[6] = RD_IN6;
assign rd_in[5] = RD_IN5;
assign rd_in[4] = RD_IN4;
assign rd_in[3] = RD_IN3;
assign rd_in[2] = RD_IN2;
assign rd_in[1] = RD_IN1;
assign rd_in[0] = RD_IN0;

assign cd_in[41] = CD_IN41;
assign cd_in[40] = CD_IN40;
assign cd_in[39] = CD_IN39;
assign cd_in[38] = CD_IN38;
assign cd_in[37] = CD_IN37;
assign cd_in[36] = CD_IN36;
assign cd_in[35] = CD_IN35;
assign cd_in[34] = CD_IN34;
assign cd_in[33] = CD_IN33;
assign cd_in[32] = CD_IN32;
assign cd_in[31] = CD_IN31;
assign cd_in[30] = CD_IN30;
assign cd_in[29] = CD_IN29;
assign cd_in[28] = CD_IN28;
assign cd_in[27] = CD_IN27;
assign cd_in[26] = CD_IN26;
assign cd_in[25] = CD_IN25;
assign cd_in[24] = CD_IN24;
assign cd_in[23] = CD_IN23;
assign cd_in[22] = CD_IN22;
assign cd_in[21] = CD_IN21;
assign cd_in[20] = CD_IN20;
assign cd_in[19] = CD_IN19;
assign cd_in[18] = CD_IN18;
assign cd_in[17] = CD_IN17;
assign cd_in[16] = CD_IN16;
assign cd_in[15] = CD_IN15;
assign cd_in[14] = CD_IN14;
assign cd_in[13] = CD_IN13;
assign cd_in[12] = CD_IN12;
assign cd_in[11] = CD_IN11;
assign cd_in[10] = CD_IN10;
assign cd_in[9] = CD_IN9;
assign cd_in[8] = CD_IN8;
assign cd_in[7] = CD_IN7;
assign cd_in[6] = CD_IN6;
assign cd_in[5] = CD_IN5;
assign cd_in[4] = CD_IN4;
assign cd_in[3] = CD_IN3;
assign cd_in[2] = CD_IN2;
assign cd_in[1] = CD_IN1;
assign cd_in[0] = CD_IN0;

assign flush = FLUSH;
assign tlb_we = TLB_WE;

assign asel  = ASEL;
assign addr[3] = ADDR3;
assign addr[2] = ADDR2;
assign addr[1] = ADDR1;
assign addr[0] = ADDR0;

assign  co_in = CO_IN;
assign  cr = CR;

assign  clk = CLK;
assign  rst = RST;


assign scm = 1'b0;
assign scn_in = 1'b0;
assign tg_strobe = 1'b1;

// assign  scm = SCM;
// assign  scn_in = SCN_IN;
// assign  tg_strobe = TG_STROBE;
// assign  pdm = PDM;
// assign SCN_OUT = scn_out;

//-----------------------------------------------------------------------
//-----------------------------------------------------------------------


wire [15:0] ram_address;
wire [27:0] ram_data_in;
wire tg_stb_clk;

// synopsys translate_off
always @(posedge clk) begin
    tlbwe_display;
end

task tlbwe_display;
if(tlb_we & ~scm) begin
	$display("\nIOTLB write to entry %d TAG = %h RAM = %h\n",addr,cd_in,rd_in);
	end
endtask

// synopsys translate_on
iocam IOTLB_cam(.ram_address (ram_address),         // TLB RAM address output
            .ram_data_in (ram_data_in),         // TLB RAM data input ( registered version of rd_in )
            .ram_write (ram_write),      // WRITE STROBE from CAM to RAM
            .cd_out (cd_out),         // TLB CAM output
            .miss (miss),             // TLB miss output (based on match op)
            .flush_op (flush_op),     // TLB flush
            .acc_ok (acc_ok),         // protection & modified bits OK & ~miss
            .error (error),           // protection check failed & ~miss
            .m_miss (m_miss),         // modified bit from CAM
            .scn_out (scn_out),       // Scan output of internal registers
            .rd_in (rd_in),           // RAM data input
            .cd_in (cd_in),          // CAM data input
            .flush (flush),          // flush control input
            .tlb_we (tlb_we),         // RAM and CAM write enable
            .asel (asel),           // Address select (1 means use addr)
            .addr (addr),           // 4-bit address for writes and reads
            .co_in (co_in),          // Compare override for IO and PTP bits
            .cr (cr),             // CAM direct address read control input
            .scm (scm),            // Scan mode control input
            .scn_in (scn_in),         // Scan input for internal registers
            .tg_strobe (tg_strobe),      // Test generation strobe (for scan ops)
            .tg_stb_clk (tg_stb_clk),    // ouput scan trigger clock to sram
            .clk (clk),            // Clock for internal registers
            .rst (rst));           // Reset for internal registers


iosram IOTLB_ram (
        .decoded_addr (ram_address),
        .do (rd_out),
        .di (ram_data_in),
        .we (ram_write),
        .flush_op (flush_op),
        .miss (miss),
        .clk (tg_stb_clk));

endmodule



[Up: IOTLB IOTLB_cam]
module iocam(ram_address,         // TLB RAM address output            
           ram_data_in,         // TLB RAM data input ( registered version of rd_in )
                ram_write,      // WRITE STROBE from CAM to RAM

                cd_out,         // TLB CAM output
                miss,           // TLB miss output (based on match op)
                flush_op,       // 
                acc_ok,         // protection & modified bits OK & ~miss
                error,          // protection check failed & ~miss
                m_miss,         // modified bit from CAM
                scn_out,        // Scan output of internal registers

                rd_in,          // RAM data input
                cd_in,          // CAM data input
                flush,          // flush control input
                tlb_we,         // RAM and CAM write enable
                asel,           // Address select (1 means use addr)
                addr,           // 6-bit address for writes and reads
                co_in,          // Compare override for IO and PTP bits
                cr,             // CAM direct address read control input
                scm,            // Scan mode control input
                scn_in,         // Scan input for internal registers
                tg_strobe,      // Test generation strobe (for scan ops)
                tg_stb_clk,     // output tg scan clock to sram as clock
                clk,            // Clock for internal registers
                rst);           // Reset for internal registers
 
    output [15:0] ram_address;    
    output [27:0] ram_data_in;
    output ram_write;
    output [41:0]  cd_out;   // tlb tag output data
    output miss;
    output flush_op;
    output acc_ok;
    output error;
    output m_miss;
    output scn_out;
 
    input [27:0] rd_in;     // tlb data input
    input [41:0] cd_in;      // tlb tag in compare data
 
    input flush;                      // flush input for TLB, clears matching
                                      //    CAM entry if any
    input tlb_we;                     // tlb tag write enable from SM
    input asel;                       // ASI decoded to tlb, selects line
                                      //    for direct read or write
                                      //    based on addr
    input [3:0] addr;                 // IOTLBN Address (4-bits), selects
    input co_in;                      // flush all comp input
    input cr;                         // CAM read
    input scm,scn_in,tg_strobe;
    output tg_stb_clk;
    input clk;
    input rst;                        // active high reset

/****************************************************************************/
/*** Variable declartions and initialization                              ***/
/****************************************************************************/

    wire [15:0] ram_address;
    wire [27:0] ram_data_in;
    wire ram_write;

//  Input register wire declaraitions

    wire tlb_we_reg, flush_reg, asel_reg, co_in_reg;
    wire [3:0] addr_reg;
    wire [`IOTLBTAG_WIDTH-1:0] c_data_in_reg;
    wire [`IOTLBDATA_WIDTH-1:0] r_data_in_reg;
    wire [15:00] hit ;
    wire [15:00] err ;
    wire [15:00] m_ok ;

// wire definition of cam line output 

 wire [41:0] tag15_out;
 wire [41:0] tag14_out;
 wire [41:0] tag13_out;
 wire [41:0] tag12_out;
 wire [41:0] tag11_out;
 wire [41:0] tag10_out;
 wire [41:0] tag09_out;
 wire [41:0] tag08_out;
 wire [41:0] tag07_out;
 wire [41:0] tag06_out;
 wire [41:0] tag05_out;
 wire [41:0] tag04_out;
 wire [41:0] tag03_out;
 wire [41:0] tag02_out;
 wire [41:0] tag01_out;
 wire [41:0] tag00_out;



// Intermediate values used in TLB internals

    wire [41:0] tlb_tag;
    wire [15:0] tag_hld;


/*** Internal Registers ****************************************************/
// Register version of signal tlb_we,flush,addr,asel
// Scan Chain needs to be defined by Megacell design
// TEMPORARY scan chain is connected as follows:
// Scan order ->addr[0:5]->cd_in[23:18]->cd_in[24]
//            ->cd_in[30:25]->cd_in[31]->cd_in[39:32]
//            ->cd_in[40]->cd_in[17:10]->cd_in[3]
//            ->cd_in[2:1]->co_in->asel
//            ->flush->tlb_we->rst->cr
//            ->cd_in[41]->cd_in[9,8,6,5,7,4]
//            ->cd_in[0]->rd_in[0:27]->scn_out
 
 
Mflipflop_s     rst_ff(rst_reg,rst,scm,tlb_we_reg,clk);
Mflipflop_s     tlb_we_ff(tlb_we_reg,tlb_we,scm,flush_reg,clk);
Mflipflop_s     co_in_ff(co_in_reg,co_in,scm,c_data_in_reg[1],clk);
Mflipflop_s     c_rd_ff(c_rd_reg,cr,scm,rst_reg,clk);
Mflipflop_s     flush_ff(flush_reg,flush,scm,asel_reg,clk);
Mflipflop_s     asel_ff(asel_reg,asel,scm,co_in_reg,clk);
IOMflipflop_s_4_r addr_ff(addr_reg,addr,scm,scn_in,clk);

// group scan order for cd_in
 
IOMflipflop_s_6_old  c_data_in_1_ff(c_data_in_reg[23:18],cd_in[23:18],scm,addr_reg[3],clk);
Mflipflop_s        c_data_in_2_ff(c_data_in_reg[24],cd_in[24],scm,c_data_in_reg[18],clk);
IOMflipflop_s_6_old  c_data_in_3_ff(c_data_in_reg[30:25],cd_in[30:25],scm,c_data_in_reg[24],clk);
Mflipflop_s        c_data_in_4_ff(c_data_in_reg[31],cd_in[31],scm,c_data_in_reg[25],clk);
IOMflipflop_s_8_old  c_data_in_5_ff(c_data_in_reg[39:32],cd_in[39:32],scm,c_data_in_reg[31],clk);
Mflipflop_s        c_data_in_6_ff(c_data_in_reg[40],cd_in[40],scm,c_data_in_reg[32],clk);
IOMflipflop_s_8_old  c_data_in_7_ff(c_data_in_reg[17:10],cd_in[17:10],scm,c_data_in_reg[40],clk);
Mflipflop_s        c_data_in_8_ff(c_data_in_reg[3],cd_in[3],scm,c_data_in_reg[10],clk);
IOMflipflop_s_2_old  c_data_in_9_ff(c_data_in_reg[2:1],cd_in[2:1],scm,c_data_in_reg[3],clk);
 
// second group of scan connection
 
Mflipflop_s    c_data_in_10_ff(c_data_in_reg[41],cd_in[41],scm,c_rd_reg,clk);
Mflipflop_s    c_data_in_11_ff(c_data_in_reg[9],cd_in[9],scm,c_data_in_reg[41],clk);
Mflipflop_s    c_data_in_12_ff(c_data_in_reg[8],cd_in[8],scm,c_data_in_reg[9],clk);
Mflipflop_s    c_data_in_13_ff(c_data_in_reg[6],cd_in[6],scm,c_data_in_reg[8],clk);
Mflipflop_s    c_data_in_14_ff(c_data_in_reg[5],cd_in[5],scm,c_data_in_reg[6],clk);
Mflipflop_s    c_data_in_15_ff(c_data_in_reg[7],cd_in[7],scm,c_data_in_reg[5],clk);
Mflipflop_s    c_data_in_16_ff(c_data_in_reg[4],cd_in[4],scm,c_data_in_reg[7],clk);
Mflipflop_s    c_data_in_17_ff(c_data_in_reg[0],cd_in[0],scm,c_data_in_reg[4],clk);
 
// end of second group signal
 
IOMflipflop_s_28_r        r_data_in_ff(r_data_in_reg,rd_in,scm,c_data_in_reg[0],clk);

assign ram_data_in = r_data_in_reg; // output a register verison rd_in to ram
 
// wire the scan out pin ....
 
wire scn_out = r_data_in_reg[27];

//  clock for tg_strobe or regular clock 
  
wire tg_stb_clk = clk & tg_strobe; 

/****************************************************************************/
/*** TLB function decode of control registers                             ***/
/****************************************************************************/
//  register version of tg_cam_read_c1
//  In scan , we need to genetare internal cam_read_op at second cam_read cycle
//  the tg_cam_read_op is to generate second cam read
    
    wire cam_read_c1;


    wire scm_reg;
    MflipflopR_1 scam_mode_reg(scm_reg,scm,tg_stb_clk,1'b0,1'b0);

// since in this model we use posedge to do operation
// we need to avoid the destruct operation do twice like tlb_write or flush_op

    wire scm_reg_2;
    MflipflopR_1 scam_mode_reg_2(scm_reg_2,scm_reg,tg_stb_clk,1'b0,1'b0);

    wire tg_cam_read_c1_op = cam_read_c1 & scm_reg;

// chop second write or flush operation

    wire chop_strobe = ~(scm_reg & scm_reg_2) & scm_reg_2;

    wire tg_cam_read_op;
    MflipflopR_1 tg_cam_read_reg(tg_cam_read_op,tg_cam_read_c1_op,tg_stb_clk,1'b0,1'b0);


// since CAM read is a 2 cycle operation, we need to register 1st decode
// decode two cycle pattern for direct cam read

    assign cam_read_c1 = (asel_reg & ~tlb_we_reg & c_rd_reg & ~flush_reg ) & ~rst_reg & ~scm & ~tg_cam_read_op;

// register cam_read_c1 operation 

    wire cam_read_c1_reg;
    MflipflopR_1 cam_read_c1_reg_1(cam_read_c1_reg,cam_read_c1,tg_stb_clk,1'b0,1'b0);

    wire cam_read_op = ((asel_reg & ~tlb_we_reg & ~c_rd_reg &
                         ~flush_reg & cam_read_c1_reg) | tg_cam_read_op ) & ~rst_reg & ~scm;


/************** start operation decode ***********************/

    wire ram_read_op = ((asel_reg & ~tlb_we_reg & ~c_rd_reg &
                                ~flush_reg ) | rst_reg) & ~scm;
 
    wire tlb_write_op = (asel_reg & tlb_we_reg & ~c_rd_reg &
                                ~flush_reg ) & ~rst_reg & ~scm & ~chop_strobe;
 
    wire match_op = (~asel_reg & ~tlb_we_reg & ~c_rd_reg &
                                ~flush_reg ) & ~rst_reg & ~scm;
 
    wire flush_op = (~asel_reg & ~tlb_we_reg & ~c_rd_reg &
                                 flush_reg ) & ~rst_reg & ~scm & ~chop_strobe;


// An illegal operation is when no legal operation was decoded.
// This is a strict check to the TLB spec.

    wire illegal_op = ~cam_read_op
                & ~cam_read_c1
                & ~ram_read_op
                & ~tlb_write_op
                & ~match_op
                & ~flush_op & ~scm & ~chop_strobe;


// synopsys translate_off

`ifdef DEBUG

// for cam_read cycle 1

   always @(posedge cam_read_c1) begin #1
       force cd_out = `IOTLBTAG_WIDTH'bx;
       force miss = 1'bx;
       force error = 1'bx;
       force acc_ok = 1'bx;
       force m_miss = 1'bx;
   end
 
   always @(negedge cam_read_c1) begin
       release cd_out;
       release miss;
       release error;
       release acc_ok;
       release m_miss;
   end
 
// for cam_read cycle 2
 
   always @(posedge cam_read_op) begin #1
       force `SSPARC_CORE.ssparc_pcic.afxm.io_tlb.rd_out = `IOTLBDATA_WIDTH'bx;
       force miss = 1'bx;
       force error = 1'bx;
       force acc_ok = 1'bx;
       force m_miss = 1'bx;
   end 
 
   always @(negedge cam_read_op) begin
       release `SSPARC_CORE.ssparc_pcic.afxm.io_tlb.rd_out ;
       release miss ;
       release error ;
       release acc_ok ;
       release m_miss ;
   end

// for direct ram read
 
   always @(posedge ram_read_op) begin #1
       force cd_out = `IOTLBTAG_WIDTH'bx;
   end
 
   always @(negedge ram_read_op) begin
       release cd_out ;
   end
 
// for campare read
// no force for campare read , all output are valid for this cycle
 
// for direct cam/ram write
 
   always @(posedge tlb_write_op) begin #1
       force miss = 1'bx;
       force error = 1'bx;
       force acc_ok = 1'bx;
       force m_miss = 1'bx;
   end
 
   always @(negedge tlb_write_op) begin
       release miss ;
       release error ;
       release acc_ok ;
       release m_miss ;
   end
 
 
// for flush entry
 
 
   always @(posedge flush_op) begin #1
       force cd_out = `IOTLBTAG_WIDTH'bx;
       force `SSPARC_CORE.ssparc_pcic.afxm.io_tlb.rd_out = `IOTLBDATA_WIDTH'bx;
       force miss = 1'bx;
       force error = 1'bx;
       force acc_ok = 1'bx;
       force m_miss = 1'bx;
   end
 
   always @(negedge flush_op) begin
       release cd_out ;
       release `SSPARC_CORE.ssparc_pcic.afxm.io_tlb.rd_out ;
       release miss ;
       release error ;
       release acc_ok ;
       release m_miss ;
   end
 
 
// end of special force procedure
 
`endif 

// 1. Check if illegal CAM read op
// 2. Check if illegal operation

    integer i,hit_no;

    always @(negedge tg_stb_clk) begin

        if ( cam_read_c1_reg && ~cam_read_op && ~scm) begin
            $display("\n******* ERROR : the control of direct IOCAM read is not correct in two cycles\n");
	    Mclocks.error_count = Mclocks.error_count + 1 ;
        end

        if ((illegal_op === 1'b1 | illegal_op === 1'bx) & ~rst_reg & ~scm) begin
            $display("\n*** ERROR: undefined IOTLB operation (illegal_op=%b) in cycle (%0d)\n",
                 illegal_op,Mclocks.cycle_count,
                "***\tasel_reg=%b, tlb_we_reg=%b, flush_reg=%b, c_rd_reg=%b, rst=%b\n",
                asel_reg, tlb_we_reg,  flush_reg, c_rd_reg, rst);
            Mclocks.error_count = Mclocks.error_count + 1 ;
        end

//        if (tlb_write_op & ~rst_reg) begin
//           if (^{c_data_in_reg[`VALIDBIT],
//                   c_data_in_reg[`PTP_BIT],
//                    c_data_in_reg[`IO_PTE],
//                c_data_in_reg[`SUPERVISOR],
//                    c_data_in_reg[`IMASK0],
//                    c_data_in_reg[`IMASK1],
//                    c_data_in_reg[`IMASK2]} === 1'bx) begin
//                   $display("\n*** ERROR: IOTLB control bits in c_data_in are unknown\n",
//                           "***\tvalid=%b ptp=%b io_pte=%b sup=%b imask0=%b imask1=%b imask2=%b\n",
//                           c_data_in_reg[`VALIDBIT], c_data_in_reg[`PTP_BIT],
//                           c_data_in_reg[`IO_PTE], c_data_in_reg[`SUPERVISOR],
//                           c_data_in_reg[`IMASK0], c_data_in_reg[`IMASK1],
//                           c_data_in_reg[`IMASK2]);
//                   Mclocks.error_count = Mclocks.error_count + 1 ;
//           end
//        end
 
        if ((match_op === 1'b1 ) & ~rst_reg & ~scm) begin
              hit_no = 0;
              for ( i=0 ; i <= 63; i=i+1) begin
                 if (hit[i] === 1'b1)
                     hit_no = hit_no+1;
              end
              if (hit_no > 1) begin
                $display("\n*** ERROR (SMOKE DETECT IOTLB!!): more than 1",
                " (%0d) TLB CAM line matched in cycle %0d = %h ",hit_no,Mclocks.cycle_count,Mclocks.cycle_count);
                $display("                  3210987654321098765432109876543210987654321098765432109876543210  ");
                $display("matching entries: %b",hit);
                Mclocks.error_count = Mclocks.error_count + 1 ;
              end
 
        end
    end

`ifdef MMU_GATE_LEVEL
`else
// monitor tlb writes for smoke detect.
//
   always @(posedge tlb_write_op & c_data_in_reg[41]) begin #16
    hit_no = 0;
              for ( i=0 ; i <= 15; i=i+1) begin
                 if (hit[i] === 1'b1)
                     hit_no = hit_no+1;
              end
              if (hit_no > 1) begin
                $display("\n*** ERROR (SMOKE DETECT  IO): more than 1",
                " (%0d) TLB CAM line matched in cycle %0d = %h ",hit_no,Mclocks.cycle_count,Mclocks.cycle_count);
                $display("                  3210987654321098765432109876543210987654321098765432109876543210  ");
                $display("matching entries: %b",hit);
                Mclocks.error_count = Mclocks.error_count + 1 ;
              end
   end

// monitor for flush context,region,segment and all operation
// register flush_done first

    reg r_flush_done;
    reg [`IOTLBTAG_WIDTH-1:0] tlb_t_tag;    

    always @(posedge tg_stb_clk) begin
       r_flush_done = `SSPARC_CORE.ssparc_mmu.MMU_cntl.tw_sm.flush_done;
    end

// connect the external wire here

    reg flush_t_ioall;
    always @(posedge clk) begin
        flush_t_ioall = `SSPARC_CORE.ssparc_mmu.MMU_cntl.tw_sm.flush_ioall;
    end
    wire flush_t_seg = `SSPARC_CORE.ssparc_mmu.MMU_cntl.tw_sm.flush_tlb_seg;
    wire flush_t_reg = `SSPARC_CORE.ssparc_mmu.MMU_cntl.tw_sm.flush_tlb_reg;
    wire flush_t_ctx = `SSPARC_CORE.ssparc_mmu.MMU_cntl.tw_sm.flush_tlb_ctx;
    wire flush_t_all = `SSPARC_CORE.ssparc_mmu.MMU_cntl.tw_sm.flush_tlb_all;
    wire vptp_mode = `SSPARC_CORE.ssparc_mmu.MMU_cntl.tw_sm.virt_ptp2;
    wire flush_t_iopte = `SSPARC_CORE.ssparc_mmu.MMU_cntl.tw_sm.flush_iopte;


    always @(negedge tg_stb_clk) begin
       if ( r_flush_done ) begin
          if ( flush_t_seg | flush_t_reg | flush_t_ctx ) begin
              for(i=0; i<`IOTLBENTRIES ; i=i+1) begin : ptp_check
                case(i)
                  0: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag00_out;
                  1: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag01_out;
                  2: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag02_out;
                  3: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag03_out;
                  4: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag04_out;
                  5: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag05_out;
                  6: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag06_out;
                  7: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag07_out;
                  8: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag08_out;
                  9: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag09_out;
                  10: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag10_out;
                  11: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag11_out;
                  12: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag12_out;
                  13: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag13_out;
                  14: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag14_out;
                  15: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag15_out;
                endcase
                if (tlb_t_tag[`PTP_BIT] && tlb_t_tag[`VALIDBIT] && tlb_t_tag[`IO_PTE]) begin 
                   $display("**iovptp entry left at %0d : after cntx, reg, or seg flush ",i);
                   $display("%h",tlb_t_tag);
                    Mclocks.error_count = Mclocks.error_count + 1 ;
                    disable ptp_check;
                end
                else if (tlb_t_tag[`PTP_BIT] && tlb_t_tag[`VALIDBIT]) begin 
                   $display("**ioptp entry left at %0d : after cntx, reg, or seg flush ",i);
                   $display("%h",tlb_t_tag);
                    Mclocks.error_count = Mclocks.error_count + 1 ;
                    disable ptp_check;
                end
              end
          end

          if ( flush_t_all ) begin
              for(i=0; i<`TLBENTRIES ; i=i+1) begin : valid_check
                case(i)
                  0: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag00_out;
                  1: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag01_out;
                  2: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag02_out;
                  3: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag03_out;
                  4: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag04_out;
                  5: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag05_out;
                  6: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag06_out;
                  7: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag07_out;
                  8: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag08_out;
                  9: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag09_out;
                  10: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag10_out;
                  11: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag11_out;
                  12: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag12_out;
                  13: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag13_out;
                  14: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag14_out;
                  15: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag15_out;
                endcase
                if ( tlb_t_tag[`VALIDBIT] ) begin
                   $display("*** first iovalid  left at %0d : after flush all ",i);
                   Mclocks.error_count = Mclocks.error_count + 1 ;
                   disable valid_check;
                end
              end
          end
       end
    end
    wire flush_ioall_cycle = flush_op & flush_t_ioall;
    reg flush_ioall_cycle_reg;
    always @(posedge tg_stb_clk) begin
      flush_ioall_cycle_reg = flush_ioall_cycle;
    end
    always @(negedge tg_stb_clk) begin
      if (flush_ioall_cycle_reg) begin
         for(i=0; i<`IOTLBENTRIES ; i=i+1) begin : iopte_check
                case(i)
                  0: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag00_out;
                  1: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag01_out;
                  2: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag02_out;
                  3: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag03_out;
                  4: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag04_out;
                  5: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag05_out;
                  6: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag06_out;
                  7: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag07_out;
                  8: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag08_out;
                  9: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag09_out;
                  10: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag10_out;
                  11: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag11_out;
                  12: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag12_out;
                  13: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag13_out;
                  14: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag14_out;
                  15: tlb_t_tag = `MMU.MMU_tlb.TLB_cam.tag15_out;
                endcase
                if (tlb_t_tag[`VALIDBIT] && tlb_t_tag[`IO_PTE]) begin
                   $display("*** ioiopte entry left at %0d : after iopte flush all",i);
                   $display("%h",tlb_t_tag);
                   Mclocks.error_count = Mclocks.error_count + 1 ;
                   disable iopte_check;
                end
         end
      end
    end
`endif


// synopsys translate_on   


/**************** ram write addres decode and WE cntrol **************/
// if direct read or write , we put ram address as decode address .
// if not , we put is to default address which is 00 

    assign ram_address = ( asel_reg ) ? decode(addr_reg) : 
                         ((match_op | flush_op) & ~rst_reg ) ?  hit : 16'h0000;

/*****************************************************************************/
// Direct write operation
// tag write is asserted directly from tag_hld to cam line input
// switch ram write control off if this is not a write operation
// tag_hld assert when tlb_write-op is true , in order to finish write
// in clk = 0 cycle. I use the ~clk to be the cam cell clk 

    assign ram_write =  tlb_write_op; 
    

/****************************************************************************/
// Direct addressed cam read.
// If clk is low and cam_read_op is decode . 
// emulation cam pre-charge high
// 
     
    wire [41:0] cd_out = (cam_read_op) ? tlb_tag : 
                               (~cam_read_c1) ? c_data_in_reg : 42'h3ffffffffff;
 
   



/****************************************************************************/
// Direct addressed ram read.and compare read & flush status output
//
// if none of ram_read_op or match_op , we set it to o.k. in 1 for synopsys 
// DIRECT ram read equation 
//      if (ram_read_op) begin
//        acc_ok_reg = 1'b1; 
//        error_reg = 1'b0;
//        miss_reg = 1'b0;
//        m_miss_reg = 1'b0;
//      end
 
 
 
 
/******************************************************************************/
//  CAM match detect.  Could be doing either a content-addressed read,
//     or a flush.  In either case, first see if we get a tag match.
//      if ((match_op | flush_op) & ~rst_reg) begin
//        miss_reg = ~(|(hit[63:0])) ;
//        error_reg = |(err[63:0]) ;
//        m_ok_reg =  |(m_ok[63:0]) ;
//        m_miss_reg = miss_reg | ~m_ok_reg;
//        acc_ok_reg = m_ok_reg & ~error_reg & ~miss_reg ;
//      end



    wire miss = ((match_op | flush_op) & ~rst_reg) &  ~(|(hit[15:0])); 
 
    wire error = ((match_op | flush_op) & ~rst_reg) & (|(err[15:0]));  

    wire m_ok_reg = ~((match_op | flush_op) & ~rst_reg) | (|(m_ok[15:0]));   
 
    wire acc_ok = ~((match_op | flush_op) & ~rst_reg) | (m_ok_reg & ~error & ~miss);

    wire m_miss = ((match_op | flush_op) & ~rst_reg) & (miss | ~m_ok_reg); 



    
///////////////////////////////////////////////////////////////////////////////
// decoder ( 4-16 decoder )

function [15:0] decode;
input [3:0] input_addr;
reg [15:0] count;
integer k;

begin

   count = 0;
   for (k=0; k <= 15; k=k+1)
      if (k == input_addr)
        count[k] = 1'b1;
   decode = count;
end
endfunction


/********************** start cam block **************************/
/****************************************************************************/
/*** Instantiate CAM lines                                                ***/

wire flush_real = flush_reg & ~scm;
wire co_in_real = co_in_reg & ~scm;

IOCAM_LINE tag00(hit[00],err[00],m_ok[00],tag00_out,
                c_data_in_reg,tg_stb_clk,tag_hld[00],flush_real,co_in_real) ;
IOCAM_LINE tag01(hit[01],err[01],m_ok[01],tag01_out,
                c_data_in_reg,tg_stb_clk,tag_hld[01],flush_real,co_in_real) ;
IOCAM_LINE tag02(hit[02],err[02],m_ok[02],tag02_out,
                c_data_in_reg,tg_stb_clk,tag_hld[02],flush_real,co_in_real) ;
IOCAM_LINE tag03(hit[03],err[03],m_ok[03],tag03_out,
                c_data_in_reg,tg_stb_clk,tag_hld[03],flush_real,co_in_real) ;
IOCAM_LINE tag04(hit[04],err[04],m_ok[04],tag04_out,
                c_data_in_reg,tg_stb_clk,tag_hld[04],flush_real,co_in_real) ;
IOCAM_LINE tag05(hit[05],err[05],m_ok[05],tag05_out,
                c_data_in_reg,tg_stb_clk,tag_hld[05],flush_real,co_in_real) ;
IOCAM_LINE tag06(hit[06],err[06],m_ok[06],tag06_out,
                c_data_in_reg,tg_stb_clk,tag_hld[06],flush_real,co_in_real) ;
IOCAM_LINE tag07(hit[07],err[07],m_ok[07],tag07_out,
                c_data_in_reg,tg_stb_clk,tag_hld[07],flush_real,co_in_real) ;
IOCAM_LINE tag08(hit[08],err[08],m_ok[08],tag08_out,
                c_data_in_reg,tg_stb_clk,tag_hld[08],flush_real,co_in_real) ;
Next12
HierarchyFilesModulesSignalsTasksFunctionsHelp

This page: Created:Thu Aug 19 11:56:43 1999
From: ../../../sparc_v8/ssparc/pcic/afxmaster/rtl/io_e_tlb.v

Verilog converted to html by v2html 5.0 (written by Costas Calamvokis).Help