annotate core/src/MemArb.bsv @ 67:0ede0715dbd6 pygar svn.68

[svn r68] added sensible benchmarks
author rlm
date Tue, 11 May 2010 23:23:21 -0400
parents 91a1f76ddd62
children
rev   line source
punk@1 1 // The MIT License
punk@1 2
punk@1 3 // Copyright (c) 2009 Massachusetts Institute of Technology
punk@1 4
punk@1 5 // Permission is hereby granted, free of charge, to any person obtaining a copy
punk@1 6 // of this software and associated documentation files (the "Software"), to deal
punk@1 7 // in the Software without restriction, including without limitation the rights
punk@1 8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
punk@1 9 // copies of the Software, and to permit persons to whom the Software is
punk@1 10 // furnished to do so, subject to the following conditions:
punk@1 11
punk@1 12 // The above copyright notice and this permission notice shall be included in
punk@1 13 // all copies or substantial portions of the Software.
punk@1 14
punk@1 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
punk@1 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
punk@1 17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
punk@1 18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
punk@1 19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
punk@1 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
punk@1 21 // THE SOFTWARE.
punk@1 22
punk@1 23 import Connectable::*;
punk@1 24 import GetPut::*;
punk@1 25 import ClientServer::*;
punk@1 26 import FIFOF::*;
punk@1 27 import FIFO::*;
punk@1 28
punk@1 29 import BFIFO::*;
punk@1 30 import MemTypes::*;
punk@1 31 import Trace::*;
punk@1 32
punk@1 33 interface MemArb;
punk@1 34
punk@1 35 interface Server#(MainMemReq,MainMemResp) cache0_server;
punk@1 36 interface Server#(MainMemReq,MainMemResp) cache1_server;
punk@1 37 interface Client#(MainMemReq,MainMemResp) mmem_client;
punk@1 38
punk@1 39 endinterface
punk@1 40
punk@1 41 typedef enum { REQ0, REQ1 } ReqPtr deriving(Eq,Bits);
punk@1 42
punk@1 43 (* synthesize *)
punk@1 44 module mkMemArb( MemArb );
punk@1 45
punk@1 46 //-----------------------------------------------------------
punk@1 47 // State
punk@1 48
punk@1 49 FIFOF#(MainMemReq) req0Q <- mkFIFOF1();
punk@1 50 FIFO#(MainMemResp) resp0Q <- mkFIFO1();
punk@1 51
punk@1 52 FIFOF#(MainMemReq) req1Q <- mkFIFOF1();
punk@1 53 FIFO#(MainMemResp) resp1Q <- mkFIFO1();
punk@1 54
punk@1 55 FIFO#(MainMemReq) mreqQ <- mkFIFO1();
punk@1 56 FIFO#(MainMemResp) mrespQ <- mkFIFO1();
punk@1 57
punk@1 58 Reg#(ReqPtr) nextReq <- mkReg(REQ0);
punk@1 59
punk@1 60 //-----------------------------------------------------------
punk@1 61 // Some wires
punk@1 62
punk@1 63 let req0avail = req0Q.notEmpty();
punk@1 64 let req1avail = req1Q.notEmpty();
punk@1 65
punk@1 66 //-----------------------------------------------------------
punk@1 67 // Rules
punk@1 68
punk@1 69 rule chooseReq0 ( req0avail && (!req1avail || (nextReq == REQ0)) );
punk@1 70 traceTiny("mkMemArb", "memArb req0",req0Q.first());
punk@1 71
punk@1 72 // Rewrite tag field if this is a load ...
punk@1 73 MainMemReq mreq
punk@1 74 = case ( req0Q.first() ) matches
punk@1 75 tagged LoadReq .ld : return LoadReq { tag:0, addr:ld.addr };
punk@1 76 tagged StoreReq .st : return req0Q.first();
punk@1 77 endcase;
punk@1 78
punk@1 79 // Send out the request
punk@1 80 mreqQ.enq(mreq);
punk@1 81 nextReq <= REQ1;
punk@1 82 req0Q.deq();
punk@1 83
punk@1 84 endrule
punk@1 85
punk@1 86 rule chooseReq1 ( req1avail && (!req0avail || (nextReq == REQ1)) );
punk@1 87 traceTiny("mkMemArb", "memArb req1",req1Q.first);
punk@1 88
punk@1 89 // Rewrite tag field if this is a load ...
punk@1 90 MainMemReq mreq
punk@1 91 = case ( req1Q.first() ) matches
punk@1 92 tagged LoadReq .ld : return LoadReq { tag:1, addr:ld.addr };
punk@1 93 tagged StoreReq .st : return req1Q.first();
punk@1 94 endcase;
punk@1 95
punk@1 96 // Send out the request
punk@1 97 mreqQ.enq(mreq);
punk@1 98 nextReq <= REQ0;
punk@1 99 req1Q.deq();
punk@1 100
punk@1 101 endrule
punk@1 102
punk@1 103 rule returnResp;
punk@1 104 traceTiny("mkMemArb", "resp",mrespQ.first());
punk@1 105
punk@1 106 // Use tag to figure out where to send response
punk@1 107 mrespQ.deq();
punk@1 108 let tag
punk@1 109 = case ( mrespQ.first() ) matches
punk@1 110 tagged LoadResp .ld : return ld.tag;
punk@1 111 tagged StoreResp .st : return st.tag;
punk@1 112 endcase;
punk@1 113
punk@1 114 if ( tag == 0 )
punk@1 115 resp0Q.enq(mrespQ.first());
punk@1 116 else
punk@1 117 resp1Q.enq(mrespQ.first());
punk@1 118
punk@1 119 endrule
punk@1 120
punk@1 121 //-----------------------------------------------------------
punk@1 122 // Methods
punk@1 123
punk@1 124 interface Server cache0_server;
punk@1 125 interface Put request = toPut(req0Q);
punk@1 126 interface Get response = toGet(resp0Q);
punk@1 127 endinterface
punk@1 128
punk@1 129 interface Server cache1_server;
punk@1 130 interface Put request = toPut(req1Q);
punk@1 131 interface Get response = toGet(resp1Q);
punk@1 132 endinterface
punk@1 133
punk@1 134 interface Client mmem_client;
punk@1 135 interface Get request = toGet(mreqQ);
punk@1 136 interface Put response = toPut(mrespQ);
punk@1 137 endinterface
punk@1 138
punk@1 139 endmodule
punk@1 140
punk@1 141