diff core/src/MemArb.bsv @ 1:91a1f76ddd62 pygar svn.2

[svn r2] Adding initial lab 5 source
author punk
date Tue, 13 Apr 2010 17:34:33 -0400
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/core/src/MemArb.bsv	Tue Apr 13 17:34:33 2010 -0400
     1.3 @@ -0,0 +1,141 @@
     1.4 +// The MIT License
     1.5 +
     1.6 +// Copyright (c) 2009 Massachusetts Institute of Technology
     1.7 +
     1.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy
     1.9 +// of this software and associated documentation files (the "Software"), to deal
    1.10 +// in the Software without restriction, including without limitation the rights
    1.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    1.12 +// copies of the Software, and to permit persons to whom the Software is
    1.13 +// furnished to do so, subject to the following conditions:
    1.14 +
    1.15 +// The above copyright notice and this permission notice shall be included in
    1.16 +// all copies or substantial portions of the Software.
    1.17 +
    1.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    1.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    1.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    1.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    1.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    1.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    1.24 +// THE SOFTWARE.
    1.25 +
    1.26 +import Connectable::*;
    1.27 +import GetPut::*;
    1.28 +import ClientServer::*;
    1.29 +import FIFOF::*;
    1.30 +import FIFO::*;
    1.31 +
    1.32 +import BFIFO::*;
    1.33 +import MemTypes::*;
    1.34 +import Trace::*;
    1.35 +
    1.36 +interface MemArb;
    1.37 +
    1.38 +  interface Server#(MainMemReq,MainMemResp) cache0_server;
    1.39 +  interface Server#(MainMemReq,MainMemResp) cache1_server;
    1.40 +  interface Client#(MainMemReq,MainMemResp) mmem_client;
    1.41 +
    1.42 +endinterface
    1.43 +
    1.44 +typedef enum { REQ0, REQ1 } ReqPtr deriving(Eq,Bits);
    1.45 +
    1.46 +(* synthesize *)
    1.47 +module mkMemArb( MemArb );
    1.48 +
    1.49 +  //-----------------------------------------------------------
    1.50 +  // State
    1.51 +
    1.52 +  FIFOF#(MainMemReq) req0Q  <- mkFIFOF1();
    1.53 +  FIFO#(MainMemResp) resp0Q <- mkFIFO1();
    1.54 +
    1.55 +  FIFOF#(MainMemReq) req1Q  <- mkFIFOF1();
    1.56 +  FIFO#(MainMemResp) resp1Q <- mkFIFO1();
    1.57 +
    1.58 +  FIFO#(MainMemReq)  mreqQ  <- mkFIFO1();
    1.59 +  FIFO#(MainMemResp) mrespQ <- mkFIFO1();
    1.60 +
    1.61 +  Reg#(ReqPtr) nextReq <- mkReg(REQ0);
    1.62 +
    1.63 +  //-----------------------------------------------------------
    1.64 +  // Some wires
    1.65 +
    1.66 +  let req0avail = req0Q.notEmpty();
    1.67 +  let req1avail = req1Q.notEmpty();
    1.68 +  
    1.69 +  //-----------------------------------------------------------
    1.70 +  // Rules
    1.71 +
    1.72 +  rule chooseReq0 ( req0avail && (!req1avail || (nextReq == REQ0)) );
    1.73 +    traceTiny("mkMemArb", "memArb req0",req0Q.first());
    1.74 +
    1.75 +    // Rewrite tag field if this is a load ...
    1.76 +    MainMemReq mreq
    1.77 +     = case ( req0Q.first() ) matches
    1.78 +	 tagged LoadReq  .ld : return LoadReq { tag:0, addr:ld.addr };
    1.79 +	 tagged StoreReq .st : return req0Q.first();
    1.80 +       endcase;
    1.81 +
    1.82 +    // Send out the request
    1.83 +    mreqQ.enq(mreq);
    1.84 +    nextReq <= REQ1;
    1.85 +    req0Q.deq();
    1.86 +
    1.87 +  endrule
    1.88 +
    1.89 +  rule chooseReq1 ( req1avail && (!req0avail || (nextReq == REQ1)) );
    1.90 +    traceTiny("mkMemArb", "memArb req1",req1Q.first);
    1.91 +
    1.92 +    // Rewrite tag field if this is a load ...
    1.93 +    MainMemReq mreq 
    1.94 +     = case ( req1Q.first() ) matches
    1.95 +         tagged LoadReq  .ld : return LoadReq { tag:1, addr:ld.addr };
    1.96 +	 tagged StoreReq .st : return req1Q.first();
    1.97 +       endcase;
    1.98 +
    1.99 +    // Send out the request
   1.100 +    mreqQ.enq(mreq);
   1.101 +    nextReq <= REQ0;
   1.102 +    req1Q.deq();
   1.103 +
   1.104 +  endrule
   1.105 +
   1.106 +  rule returnResp;
   1.107 +    traceTiny("mkMemArb", "resp",mrespQ.first());
   1.108 +
   1.109 +    // Use tag to figure out where to send response
   1.110 +    mrespQ.deq();
   1.111 +    let tag 
   1.112 +     = case ( mrespQ.first() ) matches
   1.113 +	 tagged LoadResp  .ld : return ld.tag;
   1.114 +	 tagged StoreResp .st : return st.tag;
   1.115 +       endcase;
   1.116 +     
   1.117 +    if ( tag == 0 ) 
   1.118 +      resp0Q.enq(mrespQ.first());                                    
   1.119 +    else
   1.120 +      resp1Q.enq(mrespQ.first());
   1.121 +
   1.122 +  endrule
   1.123 +
   1.124 +  //-----------------------------------------------------------
   1.125 +  // Methods
   1.126 +  
   1.127 +  interface Server cache0_server;
   1.128 +    interface Put request  = toPut(req0Q);
   1.129 +    interface Get response = toGet(resp0Q);
   1.130 +  endinterface
   1.131 +
   1.132 +  interface Server cache1_server;
   1.133 +    interface Put request  = toPut(req1Q);
   1.134 +    interface Get response = toGet(resp1Q);
   1.135 +  endinterface
   1.136 +
   1.137 +  interface Client mmem_client;
   1.138 +    interface Get request  = toGet(mreqQ);
   1.139 +    interface Put response = toPut(mrespQ);
   1.140 +  endinterface
   1.141 +
   1.142 +endmodule
   1.143 +
   1.144 +