LOGIN   :::   RECOVER PASS   :::   GET ACCOUNT    
Browse
  • Projects
  • Code (CVS)
  • Forums
  • News
  • Articles
  • Polls
  •  
    OpenCores
  • FAQ
  • CVS HowTo
  • Mission
  • Media
  • Tools
  • Advertise
  • Mirrors
  • Logos
  • Contact us
  • Job Opportunity
  •  
    Tools
  • Search
      
  • Download Cores (CVSGet)
  •  
    More
  • Wishbone
  • Perlilog
  • EDA tools
  • OpenTech CD
  •  
    Navigation: All forums > Cvs-checkins > Message List > Message Post

    Message

    Reply | Reply all
    Date Prev | Date Next | Thread Prev | Thread Next Date Index | Thread Index

    From: cvs at opencores.org<cvs@o...>
    Date: Mon Jun 30 18:02:13 CEST 2008
    Subject: [cvs-checkins] MODIFIED: cryptosorter ...
    Top
    Date: 00/08/06 30:18:02

    Added: cryptosorter/memocodeDesignContest2008/xup/ExternalMemory
    ExternalMemory.bsv ExternalMemoryTestbench.bsv
    ExternalMemoryTester.bsv
    Log:
    Initial checkin with actual source




    Revision Changes Path
    1.1 cryptosorter/memocodeDesignContest2008/xup/ExternalMemory/ExternalMemory.bsv

    http://www.opencores.org/cvsweb.shtml/cryptosorter/memocodeDesignContest2008/xup/ExternalMemory/ExternalMemory.bsv?rev=1.1&content-type=text/x-cvsweb-markup

    Index: ExternalMemory.bsv
    ===================================================================
    /*
    Copyright (c) 2008 MIT

    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use,
    copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following
    conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

    Author: Kermin Fleming
    */

    /* This module serves as an abstraction layer for wrapping an external memory
    system. In particular, it emulates a parametric number of
    read and write virtual channels, sheilding the user module from the actual
    details of the underlying memory system. Thus, user modules may be
    implemented targeting the same "External Memory" and then used in
    systems with radically different memory subsystems. The module orders writes
    before reads. It is additionally parameterized by address width (Addr)
    and data width.
    */


    import Memocode08Types::*;
    import Vector::*;
    import FIFOF::*;
    import Types::*;
    import Interfaces::*;
    import Parameters::*;
    import DebugFlags::*;
    import GetPut::*;

    module mkExternalMemory#(PLBMaster plbmaster) (ExternalMemory);

    FIFOF#(Bit#(TAdd#(1,TLog#(ReadPortNum)))) readRespFIFO <- mkFIFOF();
    FIFOF#(Bit#(TAdd#(1,TLog#(ReadPortNum)))) writeFIFO <- mkFIFOF();

    Reg#(Bit#(TLog#(RecordsPerBlock))) readRespCount <- mkReg(0);
    Reg#(Bit#(TLog#(RecordsPerBlock))) writeCount <- mkReg(0);
    Reg#(Bit#(TLog#(TAdd#(TAdd#(WritePortNum,ReadPortNum),1)))) outstandingCount <- mkReg(0);
    Reg#(Bit#(TLog#(TAdd#(WritePortNum,ReadPortNum)))) nextToSend <- mkReg(0);


    FIFOF#(Vector#(TAdd#(ReadPortNum, WritePortNum), Maybe#(PLBMasterCommand))) reqSnapshot <- mkSizedFIFOF(1);

    Vector#(ReadPortNum, RWire#(Addr)) readReqs <- replicateM(mkRWire);
    Vector#(WritePortNum, RWire#(Addr)) writeReqs <- replicateM(mkRWire);

    Vector#(ReadPortNum, Read) readInterfaces = newVector();
    Vector#(WritePortNum, Write) writeInterfaces = newVector();


    for(Integer i = 0; i < valueof(ReadPortNum); i = i + 1)
    begin
    readInterfaces[i] =
    interface Read;
    // Should we go round robin?
    method Action readReq(Addr addr) if(reqSnapshot.notFull());
    debug(externalMemoryDebug,$display("ReadPort %d making ReadReq %h at %d", i, addr,$time));
    readReqs[i].wset(addr);
    endmethod

    // May want to use some buffering here. Might help things out.
    method ActionValue#(Record) read() if(readRespFIFO.first() ==
    fromInteger(i));
    debug(externalMemoryDebug,$display("ReadPort %d making Read %d", i, readRespCount));
    if(readRespCount + 1 == 0)
    begin
    debug(externalMemoryDebug,$display("ReadPort %d Load Complete!", i));
    readRespFIFO.deq; readRespCount <= 0; end else begin readRespCount <= readRespCount + 1; end Record record <- plbmaster.wordOutput.get; return record; endmethod endinterface; end for(Integer i = 0; i < valueof(WritePortNum); i = i + 1) begin writeInterfaces[i] = interface Write; // Should we go round robin? SHould we delay as long as possible? method Action writeReq(Addr addr) if(reqSnapshot.notFull()); debug(externalMemoryDebug,$display("WritePort %d making WriteReq %h", i, addr)); writeReqs[i].wset(addr); endmethod // May want to use some buffering here. Might help things out. method Action write(Record record) if(writeFIFO.first() == fromInteger(i)); if(writeCount + 1 == 0) begin debug(externalMemoryDebug,$display("WritePort %d Load Complete!", i)); writeFIFO.deq; writeCount <= 0; end else begin writeCount <= writeCount + 1; end plbmaster.wordInput.put(record); endmethod endinterface; end function checkMaybe(previous, maybeVal); if(maybeVal matches tagged Valid .data) begin return True; end else begin return previous; end endfunction function castStore(addrMaybe); if(addrMaybe matches tagged Valid .addr) begin return tagged Valid StorePage(unpack(truncate(pack(addr)))); end else begin return tagged Invalid; end endfunction function castLoad(addrMaybe); if(addrMaybe matches tagged Valid .addr) begin return tagged Valid LoadPage(unpack(truncate(pack(addr)))); end else begin return tagged Invalid; end endfunction function Maybe#(Addr) callwget(RWire#(Addr) rwire); return rwire.wget; endfunction rule processReqs; Bool shouldEnq = foldl(checkMaybe,False,append(map(callwget,writeReqs),map(callwget,readReqs))); if(shouldEnq) begin debug(externalMemoryDebug,$display("Processing Reqs at %d", $time)); reqSnapshot.enq(append(map(castLoad, map(callwget,readReqs)),map(castStore,map(callwget,writeReqs)))); end endrule rule chooseReq; Maybe#(Bit#(TLog#(TAdd#(WritePortNum,ReadPortNum)))) sendTarget = tagged Invalid; for(Integer i = valueof(WritePortNum) + valueof(ReadPortNum) - 1; i >= 0; i = i - 1) begin if(reqSnapshot.first[i] matches tagged Valid .cmd &&& (fromInteger(i) >= nextToSend)) begin sendTarget = tagged Valid fromInteger(i); end end debug(externalMemoryDebug,$display("Sending Reqs, upto: %d, next index: %d", nextToSend, fromMaybe(-1,sendTarget))); if(sendTarget matches tagged Valid .index &&& reqSnapshot.first[index] matches tagged Valid .cmd) begin plbmaster.plbMasterCommandInput.put(cmd); if(cmd matches tagged LoadPage .addr) begin debug(externalMemoryDebug,$display("Issuing Load %d actual: %d", index, index)); readRespFIFO.enq(truncate(index)); end else begin debug(externalMemoryDebug,$display("Issuing Store %d actual: %d", index, index-fromInteger(valueof(WritePortNum)))); writeFIFO.enq(truncate(index-fromInteger(valueof(ReadPortNum)))); end if(index >= fromInteger(valueof(WritePortNum)+ valueof(ReadPortNum) - 1)) begin debug(externalMemoryDebug,$display("Req Q deq, due to last request")); reqSnapshot.deq; nextToSend <= 0; end else begin nextToSend <= index + 1; end end else begin debug(externalMemoryDebug,$display("Req Q deq, due to no valid requests")); nextToSend <= 0; reqSnapshot.deq; end endrule // This is conservative... method Bool readsPending(); return reqSnapshot.notEmpty || readRespFIFO.notEmpty; endmethod method Bool writesPending(); return reqSnapshot.notEmpty || writeFIFO.notEmpty; endmethod interface read = readInterfaces; interface write = writeInterfaces; endmodule 1.1 cryptosorter/memocodeDesignContest2008/xup/ExternalMemory/ExternalMemoryTestbench.bsv http://www.opencores.org/cvsweb.shtml/cryptosorter/memocodeDesignContest2008/xup/ExternalMemory/ExternalMemoryTestbench.bsv?rev=1.1&content-type=text/x-cvsweb-markup Index: ExternalMemoryTestbench.bsv =================================================================== /* Copyright (c) 2008 MIT Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Author: Kermin Fleming */ import ExternalMemory::*; import Memocode08Types::*; import Types::*; import Interfaces::*; import Parameters::*; import DebugFlags::*; import PLBMasterWires::*; import LFSR::*; import FIFOF::*; import FIFO::*; import GetPut::*; import PLBMasterDummy::*; typedef enum { Initialize, Request, Transmit } TesterState deriving(Bits,Eq); module mkExternalMemoryTestbench (Empty); Reg#(Bit#(TLog#(TDiv#(TMul#(BlockSize,WordWidth),RecordWidth)))) plbMasterCount <- mkReg(0); FIFO#(PLBMasterCommand) plbMasterCommand <- mkFIFO(); FIFO#(Record) plbWordInput <- mkFIFO(); FIFO#(Record) plbWordOutput <- mkFIFO(); PLBMaster plbmaster; plbmaster = interface PLBMaster; interface Put wordInput; method Action put(Record wordInput) if(plbMasterCommand.first matches tagged StorePage .addr); if(zeroExtend(addr) != wordInput) begin $display("Store Value %h != %h", addr, wordInput); $finish; end plbMasterCount <= plbMasterCount + 1; if(plbMasterCount + 1 == 0) begin plbMasterCommand.deq; end endmethod endinterface interface Get wordOutput; method ActionValue#(Record) get() if(plbMasterCommand.first matches tagged LoadPage .addr); $display("PLBMaster Output"); plbMasterCount <= plbMasterCount + 1; if(plbMasterCount + 1 == 0) begin $display("plbMaster load command dequed!"); plbMasterCommand.deq; end return zeroExtend(addr); endmethod endinterface interface Put plbMasterCommandInput; method Action put(PLBMasterCommand command); $display("PLB Master got a command: %s", command matches tagged LoadPage .addr?"Load":"Store"); plbMasterCommand.enq(command); endmethod endinterface interface plbMasterWires = ?; endinterface; ExternalMemory extMem <- mkExternalMemory(plbmaster); rule haltAll; Bit#(64) timeCount <- $time; if(timeCount > 1000000100) begin $display("PASSED"); $finish; end endrule for(Integer i = 0; i < valueof(ReadPortNum); i = i + 1) begin LFSR#(Bit#(16)) lfsr <- mkLFSR_16; Reg#(TesterState) state <- mkReg(Initialize); Reg#(Bit#(32)) counter <- mkReg(0); FIFOF#(Bit#(16)) expectedVals <- mkFIFOF; Reg#(Bit#(TLog#(RecordsPerBlock))) transmitCount <- mkReg(0); rule countUp; counter <= counter + 1; endrule rule init(state == Initialize); state <= Request; lfsr.seed(fromInteger(i+1)); endrule rule sendRequest((state == Request) && (counter % fromInteger(32*(i+1)) == 0)); Bit#(64) timeCount <- $time; if(timeCount < 1000000000) begin extMem.read[i].readReq(zeroExtend(lfsr.value)); lfsr.next(); expectedVals.enq(lfsr.value); end endrule rule transmit; transmitCount <= transmitCount + 1; if(transmitCount + 1 == 0) begin expectedVals.deq; end Record valueTransmitted <- extMem.read[i].read; if(valueTransmitted != zeroExtend(expectedVals.first)) begin $display("Load Value Reader[%d] %h != %h", i, expectedVals.first, valueTransmitted); $finish; end endrule rule haltCheck (expectedVals.notEmpty); Bit#(64) timeCount <- $time; if(timeCount > 11000000000) begin $display("Writer[%d] stalled out", i); $finish; end endrule end for(Integer i = 0; i < valueof(WritePortNum); i = i + 1) begin LFSR#(Bit#(16)) lfsr <- mkLFSR_16; Reg#(TesterState) state <- mkReg(Initialize); Reg#(Bit#(32)) counter <- mkReg(0); FIFOF#(Bit#(16)) expectedVals <- mkFIFOF; Reg#(Bit#(TLog#(RecordsPerBlock))) transmitCount <- mkReg(0); rule countUp; counter <= counter + 1; endrule rule init(state == Initialize); state <= Request; lfsr.seed(fromInteger(i+1+valueof(ReadPortNum))); endrule rule sendRequest((state == Request) && (counter % fromInteger(32*(i+3)) == 0)); Bit#(64) timeCount <- $time; if(timeCount < 1000000000) begin extMem.write[i].writeReq(zeroExtend(lfsr.value)); lfsr.next(); expectedVals.enq(lfsr.value); end endrule rule transmit; transmitCount <= transmitCount + 1; if(transmitCount + 1 == 0) begin expectedVals.deq; end extMem.write[i].write(zeroExtend(expectedVals.first)); endrule rule haltCheck (expectedVals.notEmpty); Bit#(64) timeCount <- $time; if(timeCount > 11000000000) begin $display("Writer[%d] stalled out", i); $finish; end endrule end endmodule 1.1 cryptosorter/memocodeDesignContest2008/xup/ExternalMemory/ExternalMemoryTester.bsv http://www.opencores.org/cvsweb.shtml/cryptosorter/memocodeDesignContest2008/xup/ExternalMemory/ExternalMemoryTester.bsv?rev=1.1&content-type=text/x-cvsweb-markup Index: ExternalMemoryTester.bsv =================================================================== /* Copyright (c) 2008 MIT Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Author: Kermin Fleming */ import ExternalMemory::*; import Memocode08Types::*; import Types::*; import Interfaces::*; import Parameters::*; import DebugFlags::*; import PLBMasterWires::*; import LFSR::*; import FIFOF::*; import FIFO::*; import GetPut::*; import Vector::*; import BRAMInitiatorWires::*; import PLBMaster::*; import BRAMFeeder::*; typedef enum { Initialize, Request, Transmit } TesterState deriving(Bits,Eq); interface ExternalMemoryTester; interface PLBMasterWires plbMasterWires; interface BRAMInitiatorWires#(Bit#(14)) bramInitiatorWires; endinterface module mkExternalMemoryTester (ExternalMemoryTester); Feeder feeder <- mkBRAMFeeder(); PLBMaster plbmaster <- mkPLBMaster; ExternalMemory extMem <- mkExternalMemory(plbmaster); Vector#(ReadPortNum,FIFO#(Bit#(16))) readTargets <- replicateM(mkFIFO); Reg#(Bit#(28)) busCounter <-mkReg(0); // Need to lay off the bus for a bit Reg#(Bool) error <- mkReg(False); rule countUp; busCounter <= busCounter + 1; endrule rule sendBackResp (busCounter == 0); if(error) begin feeder.ppcMessageInput.put(1); end error <= False; endrule for(Integer i = 0; i < valueof(ReadPortNum); i = i + 1) begin Reg#(TesterState) state <- mkReg(Initialize); FIFOF#(Bit#(16)) expectedVals <- mkFIFOF; Reg#(Bit#(TLog#(RecordsPerBlock))) transmitCount <- mkReg(0); rule init(state == Initialize); state <= Request; endrule rule sendRequest; extMem.read[i].readReq(zeroExtend(readTargets[i].first) << 4); readTargets[i].deq(); expectedVals.enq(readTargets[i].first); endrule rule transmit; transmitCount <= transmitCount + 1; if(transmitCount + 1 == 0) begin expectedVals.deq; end Record valueTransmitted <- extMem.read[i].read; if(valueTransmitted != zeroExtend(expectedVals.first)) begin error <= True; end endrule end for(Integer i = 0; i < valueof(WritePortNum); i = i + 1) begin LFSR#(Bit#(16)) lfsr <- mkLFSR_16; Reg#(TesterState) state <- mkReg(Initialize); FIFOF#(Bit#(16)) expectedVals <- mkFIFOF; Reg#(Bit#(TLog#(RecordsPerBlock))) transmitCount <- mkReg(0); rule init(state == Initialize); state <= Request; lfsr.seed(fromInteger(i+1+valueof(ReadPortNum))); endrule rule sendRequest (busCounter[27:25] == 0); extMem.write[i].writeReq(zeroExtend(lfsr.value)<<4); // Shift over for 16 byte alignment lfsr.next(); expectedVals.enq(lfsr.value); endrule rule transmit; transmitCount <= transmitCount + 1; if(transmitCount + 1 == 0) begin expectedVals.deq; readTargets[i].enq(expectedVals.first); end extMem.write[i].write(zeroExtend(expectedVals.first)); endrule end interface plbMasterWires = plbmaster.plbMasterWires; interface bramInitiatorWires = feeder.bramInitiatorWires; endmodule

     
    Copyright (c) 1999 OPENCORES.ORG. All rights reserved.