URL
https://opencores.org/ocsvn/bluespec_md6/bluespec_md6/trunk
Subversion Repositories bluespec_md6
Compare Revisions
- This comparison shows the changes necessary to convert path
/bluespec_md6/trunk/compressionFunction/fpga
- from Rev 6 to Rev 7
- ↔ Reverse comparison
Rev 6 → Rev 7
/md6engine.v
0,0 → 1,260
//----------------------------------------------------------------------// |
// The MIT License |
// |
// Copyright (c) 2008 Kermin Fleming, kfleming@mit.edu |
// |
// 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. |
//----------------------------------------------------------------------// |
/* |
Copyright (c) 2007 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 |
*/ |
|
module md6engine(CLK, |
RST, |
plbMasterWires_mABus, |
|
plbMasterWires_mBE, |
|
plbMasterWires_mRNW, |
|
plbMasterWires_mAbort, |
|
plbMasterWires_mBusLock, |
|
plbMasterWires_mCompress, |
|
plbMasterWires_mGuarded, |
|
plbMasterWires_mLockErr, |
|
plbMasterWires_mMSize, |
|
plbMasterWires_mOrdered, |
|
plbMasterWires_mPriority, |
|
plbMasterWires_mRdBurst, |
|
plbMasterWires_mRequest, |
|
plbMasterWires_mSize, |
|
plbMasterWires_mType, |
|
plbMasterWires_mWrBurst, |
|
plbMasterWires_mWrDBus, |
|
plbMasterWires_mRst, |
plbMasterWires_mAddrAck, |
plbMasterWires_mBusy, |
plbMasterWires_mErr, |
plbMasterWires_mRdBTerm, |
plbMasterWires_mRdDAck, |
plbMasterWires_mRdDBus, |
plbMasterWires_mRdWdAddr, |
plbMasterWires_mRearbitrate, |
plbMasterWires_mWrBTerm, |
plbMasterWires_mWrDAck, |
plbMasterWires_mSSize, |
plbMasterWires_sMErr, |
plbMasterWires_sMBusy, |
bramInitiatorWires_bramRST, |
bramInitiatorWires_bramAddr, |
bramInitiatorWires_bramDout, |
bramInitiatorWires_bramWEN, |
bramInitiatorWires_bramEN, |
bramInitiatorWires_bramCLK, |
bramInitiatorWires_bramDin); |
input CLK; |
input RST; |
|
// value method plbMasterWires_mABus |
output [31 : 0] plbMasterWires_mABus; |
|
// value method plbMasterWires_mBE |
output [7 : 0] plbMasterWires_mBE; |
|
// value method plbMasterWires_mRNW |
output plbMasterWires_mRNW; |
|
// value method plbMasterWires_mAbort |
output plbMasterWires_mAbort; |
|
// value method plbMasterWires_mBusLock |
output plbMasterWires_mBusLock; |
|
// value method plbMasterWires_mCompress |
output plbMasterWires_mCompress; |
|
// value method plbMasterWires_mGuarded |
output plbMasterWires_mGuarded; |
|
// value method plbMasterWires_mLockErr |
output plbMasterWires_mLockErr; |
|
// value method plbMasterWires_mMSize |
output [1 : 0] plbMasterWires_mMSize; |
|
// value method plbMasterWires_mOrdered |
output plbMasterWires_mOrdered; |
|
// value method plbMasterWires_mPriority |
output [1 : 0] plbMasterWires_mPriority; |
|
// value method plbMasterWires_mRdBurst |
output plbMasterWires_mRdBurst; |
|
// value method plbMasterWires_mRequest |
output plbMasterWires_mRequest; |
|
// value method plbMasterWires_mSize |
output [3 : 0] plbMasterWires_mSize; |
|
// value method plbMasterWires_mType |
output [2 : 0] plbMasterWires_mType; |
|
// value method plbMasterWires_mWrBurst |
output plbMasterWires_mWrBurst; |
|
// value method plbMasterWires_mWrDBus |
output [63 : 0] plbMasterWires_mWrDBus; |
|
// action method plbMasterWires_plbIN |
input plbMasterWires_mRst; |
input plbMasterWires_mAddrAck; |
input plbMasterWires_mBusy; |
input plbMasterWires_mErr; |
input plbMasterWires_mRdBTerm; |
input plbMasterWires_mRdDAck; |
input [63 : 0] plbMasterWires_mRdDBus; |
input [2 : 0] plbMasterWires_mRdWdAddr; |
input plbMasterWires_mRearbitrate; |
input plbMasterWires_mWrBTerm; |
input plbMasterWires_mWrDAck; |
input plbMasterWires_mSSize; |
input plbMasterWires_sMErr; |
input plbMasterWires_sMBusy; |
|
// action method bramTargetWires_bramIN |
output [31 : 0] bramInitiatorWires_bramAddr; |
output [31 : 0] bramInitiatorWires_bramDout; |
output [3 : 0] bramInitiatorWires_bramWEN; |
output bramInitiatorWires_bramEN; |
output bramInitiatorWires_bramCLK; |
output bramInitiatorWires_bramRST; |
|
// value method bramTargetWires_bramOUT |
input [31 : 0] bramInitiatorWires_bramDin; |
|
wire [13:0] bramInitiatorWires_bramAddr_our; |
assign bramInitiatorWires_bramAddr = {16'h0000,bramInitiatorWires_bramAddr_our, 2'b00}; |
// signals for module outputs |
wire [31 : 0] bramTargetWires_dinBRAM,plbMasterWires_mABus; |
|
wire [63 : 0] plbMasterWires_mWrDBus; |
wire [7 : 0] plbMasterWires_mBE; |
wire [3 : 0] plbMasterWires_mSize; |
wire [2 : 0] plbMasterWires_mType; |
wire [1 : 0] plbMasterWires_mMSize, plbMasterWires_mPriority; |
wire plbMasterWires_mAbort, |
plbMasterWires_mBusLock, |
plbMasterWires_mCompress, |
plbMasterWires_mGuarded, |
plbMasterWires_mLockErr, |
plbMasterWires_mOrdered, |
plbMasterWires_mRNW, |
plbMasterWires_mRdBurst, |
plbMasterWires_mRequest, |
plbMasterWires_mWrBurst; |
|
wire RST_N; |
assign RST_N = ~RST; |
|
|
mkMD6Engine m( |
.CLK(CLK), |
.RST_N(RST_N), |
|
.plbMasterWires_mABus(plbMasterWires_mABus), |
.plbMasterWires_mBE(plbMasterWires_mBE), |
.plbMasterWires_mRNW(plbMasterWires_mRNW), |
.plbMasterWires_mAbort(plbMasterWires_mAbort), |
.plbMasterWires_mBusLock(plbMasterWires_mBusLock), |
.plbMasterWires_mCompress(plbMasterWires_mCompress), |
.plbMasterWires_mGuarded(plbMasterWires_mGuarded), |
.plbMasterWires_mLockErr(plbMasterWires_mLockErr), |
.plbMasterWires_mMSize(plbMasterWires_mMSize), |
.plbMasterWires_mOrdered(plbMasterWires_mOrdered), |
.plbMasterWires_mPriority(plbMasterWires_mPriority), |
.plbMasterWires_mRdBurst(plbMasterWires_mRdBurst), |
.plbMasterWires_mRequest(plbMasterWires_mRequest), |
.plbMasterWires_mSize(plbMasterWires_mSize), |
.plbMasterWires_mType(plbMasterWires_mType), |
.plbMasterWires_mWrBurst(plbMasterWires_mWrBurst), |
.plbMasterWires_mWrDBus(plbMasterWires_mWrDBus), |
.plbMasterWires_mRst(plbMasterWires_mRst), |
.plbMasterWires_mAddrAck(plbMasterWires_mAddrAck), |
.plbMasterWires_mBusy(plbMasterWires_mBusy), |
.plbMasterWires_mErr(plbMasterWires_mErr), |
.plbMasterWires_mRdBTerm(plbMasterWires_mRdBTerm), |
.plbMasterWires_mRdDAck(plbMasterWires_mRdDAck), |
.plbMasterWires_mRdDBus(plbMasterWires_mRdDBus), |
.plbMasterWires_mRdWdAddr(plbMasterWires_mRdWdAddr), |
.plbMasterWires_mRearbitrate(plbMasterWires_mRearbitrate), |
.plbMasterWires_mWrBTerm(plbMasterWires_mWrBTerm), |
.plbMasterWires_mWrDAck(plbMasterWires_mWrDAck), |
.plbMasterWires_mSSize(plbMasterWires_mSSize), |
.plbMasterWires_sMErr(plbMasterWires_sMErr), |
.plbMasterWires_sMBusy(plbMasterWires_sMBusy), |
.bramInitiatorWires_bramAddr(bramInitiatorWires_bramAddr_our), |
.bramInitiatorWires_bramDout(bramInitiatorWires_bramDout), |
.bramInitiatorWires_bramWEN(bramInitiatorWires_bramWEN), |
.bramInitiatorWires_bramEN(bramInitiatorWires_bramEN), |
.bramInitiatorWires_bramCLK(bramInitiatorWires_bramCLK), |
.bramInitiatorWires_bramRST(bramInitiatorWires_bramRST), |
.bramInitiatorWires_din(bramInitiatorWires_bramDin) |
); |
|
endmodule |
/MD6Engine.bsv
0,0 → 1,343
//----------------------------------------------------------------------// |
// The MIT License |
// |
// Copyright (c) 2008 Kermin Fleming, kfleming@mit.edu |
// |
// 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. |
//----------------------------------------------------------------------// |
/* |
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 is the top-level sorter module. It interfaces to the PLB bus, the |
DSOCM, and the sorter core. Not much functionality, but it does have |
a cycle timer, and sends periodic messages back to the PPC over the |
DSOCM |
*/ |
|
// Bluespec Lib |
import FIFO::*; |
import GetPut::*; |
import Vector::*; |
import Connectable::*; |
|
// CSG Lib |
import PLBMasterWires::*; |
import BRAMInitiatorWires::*; |
import PLBMaster::*; |
import BRAMFeeder::*; |
import PLBMaster::*; |
import PLBMasterDefaultParameters::*; |
|
// Local includes |
import CompressionFunction::*; |
import CompressionFunctionLibrary::*; |
import MD6Parameters::*; |
import MD6Types::*; |
|
|
interface MD6Engine; |
interface PLBMasterWires plbMasterWires; |
interface BRAMInitiatorWires#(Bit#(14)) bramInitiatorWires; |
endinterface |
|
// Might consider making this size 8 at some point so that it jives with |
// other parameterizations |
typedef 16 InterfaceRegister; |
typedef Bit#(15) RegisterTag; |
|
typedef enum { |
Read = 0, |
Write = 1 |
} Command deriving (Bits,Eq); |
|
|
typedef 7 ControlRegisters; |
typedef TMul#(MD6_u,TDiv#(MD6_WordWidth,InterfaceRegister)) IdentifierRegisters; |
typedef TMul#(MD6_k,TDiv#(MD6_WordWidth,InterfaceRegister)) KeyRegisters; |
typedef 2 SourceRegisters; |
typedef 2 DestinationRegisters; |
|
typedef 0 RoundRegister; |
typedef 1 TreeHeightRegister; |
typedef 2 LastCompressionRegister; |
typedef 3 PaddingBitsRegister; |
typedef 4 KeyLengthRegister; |
typedef 5 DigestLengthRegister; |
typedef 6 CompressionFunctionStatus; |
typedef 7 KeyRegisterBase; |
typedef TAdd#(ControlRegisters,KeyRegisters) IdentifierRegisterBase; |
typedef TAdd#(ControlRegisters, TAdd#(KeyRegisters,IdentifierRegisters)) SourceRegisterBase; |
typedef TAdd#(TAdd#(ControlRegisters,IdentifierRegisters), TAdd#(KeyRegisters,SourceRegisters)) DestinationRegisterBase; |
typedef TAdd#(IdentifierRegisters,TAdd#(TAdd#(ControlRegisters,DestinationRegisters), TAdd#(KeyRegisters,SourceRegisters))) TotalRegisters; |
|
typedef TDiv#(TMul#(SizeOf#(BusWord),BeatsPerBurst), SizeOf#(MD6Word)) MD6WordsPerBurst; |
|
typedef 32'hC0000 MD6CommunicationConstant; |
|
typedef struct { |
Command command; |
RegisterTag regTag; |
Bit#(InterfaceRegister) payload; |
} IOCommand deriving (Bits,Eq); |
|
typedef enum { |
Idle, |
Load |
} LoadState deriving (Bits,Eq); |
|
typedef enum { |
Idle, |
Store |
} StoreState deriving (Bits,Eq); |
|
|
(*synthesize*) |
module mkCompressionFunction64 (CompressionFunction#(64)); |
let m <- mkMult16CompressionFunction; |
return m; |
endmodule |
|
(*synthesize*) |
module mkCompressionFunction48 (CompressionFunction#(48)); |
let m <- mkMult16CompressionFunction; |
return m; |
endmodule |
|
(*synthesize*) |
module mkCompressionFunction32 (CompressionFunction#(32)); |
let m <- mkMult16CompressionFunction; |
return m; |
endmodule |
|
(*synthesize*) |
module mkCompressionFunction16 (CompressionFunction#(16)); |
let m <- mkSimpleCompressionFunction; |
return m; |
endmodule |
|
(*synthesize*) |
module mkCompressionFunction8 (CompressionFunction#(8)); |
let m <- mkSimpleCompressionFunction; |
return m; |
endmodule |
|
(*synthesize*) |
module mkCompressionFunction4 (CompressionFunction#(4)); |
let m <- mkSimpleCompressionFunction; |
return m; |
endmodule |
|
(*synthesize*) |
module mkCompressionFunction2 (CompressionFunction#(2)); |
let m <- mkSimpleCompressionFunction; |
return m; |
endmodule |
|
(*synthesize*) |
module mkCompressionFunction1 (CompressionFunction#(1)); |
let m <- mkSimpleCompressionFunction; |
return m; |
endmodule |
|
|
module mkMD6Engine (MD6Engine); |
Feeder feeder <- mkBRAMFeeder(); |
PLBMaster plbMaster <- mkPLBMaster; |
CompressionFunction#(4) compressionFunction <- mkSimpleCompressionFunction; |
FIFO#(PPCMessage) outputFIFO <- mkFIFO; |
Vector#(TotalRegisters, Reg#(Bit#(InterfaceRegister))) interfaceRegisters <- |
replicateM(mkReg(0)); |
|
|
// Hook Control, PLBMaster and MD6 engine components together. |
// This solution WILL NOT WORK for multiple Compression functions |
mkConnection(plbMaster.wordInput.put, compressionFunction.outputWord); |
mkConnection(compressionFunction.inputWord,plbMaster.wordOutput.get); |
mkConnection(feeder.ppcMessageInput.put,(fifoToGet(outputFIFO)).get); |
|
Reg#(Bit#(TAdd#(1,TDiv#(MD6_b,MD6WordsPerBurst)))) loadCount <- mkReg(0); |
|
Reg#(Bit#(TAdd#(1,TDiv#(MD6_c,MD6WordsPerBurst)))) storeCount <- mkReg(0); |
|
Reg#(LoadState) loadState <- mkReg(Idle); |
|
Reg#(StoreState) storeState <- mkReg(Idle); |
|
FIFO#(IOCommand) incomingCommands <- mkFIFO; |
|
function IOCommand extractIOCommand(PPCMessage ppcMessage); |
IOCommand command = IOCommand {command: unpack(ppcMessage[31]), |
regTag: ppcMessage[30:16], |
payload: ppcMessage[15:0]}; |
return command; |
endfunction |
|
// This function may require its own unit test |
// It should convert interface words to MD6 Words |
function Vector#(length,MD6Word) convertWords( |
Vector#(TMul#(length,TDiv#(MD6_WordWidth,InterfaceRegister)),Bit#(InterfaceRegister)) inVector); |
Vector#(length,MD6Word) outVector = newVector; |
for(Integer totalNumber = 0; |
totalNumber < valueof(length); |
totalNumber = totalNumber + 1) |
begin |
Vector#(TDiv#(MD6_WordWidth,InterfaceRegister),Bit#(InterfaceRegister)) wordVector = newVector; |
for(Integer wordsInMD6Word = 0; |
wordsInMD6Word < valueof(TDiv#(MD6_WordWidth,InterfaceRegister)); |
wordsInMD6Word = wordsInMD6Word + 1) |
begin |
wordVector[wordsInMD6Word] = inVector[totalNumber*valueof(TDiv#(MD6_WordWidth,InterfaceRegister)) |
+wordsInMD6Word]; |
end |
outVector[totalNumber] = unpack(pack(wordVector)); // is this sane? |
end |
return outVector; |
endfunction |
|
rule getCommand; |
PPCMessage msg <- feeder.ppcMessageOutput.get; |
IOCommand command = extractIOCommand(msg); |
incomingCommands.enq(command); |
endrule |
|
// Writing to the CompressionFunctionStatus means kickoff a compression operation |
// Reading from it will grab the current status of the Compression Engine |
|
rule processWrite(incomingCommands.first.command == Write); |
incomingCommands.deq; |
|
if(fromInteger(valueof(CompressionFunctionStatus)) == incomingCommands.first.regTag) |
begin |
// we can leave this unguarded because the properties of the compression function |
// will prevent doing nasty things like confusing the order of memory accesses. |
let controlWord = makeControlWord(truncate(interfaceRegisters[valueof(RoundRegister)]), |
truncate(interfaceRegisters[valueof(TreeHeightRegister)]), |
truncate(interfaceRegisters[valueof(LastCompressionRegister)]), |
truncate(interfaceRegisters[valueof(PaddingBitsRegister)]), |
truncate(interfaceRegisters[valueof(KeyLengthRegister)]), |
truncate(interfaceRegisters[valueof(DigestLengthRegister)])); |
|
compressionFunction.start(convertWords(takeAt(valueof(IdentifierRegisterBase),readVReg(interfaceRegisters))), |
controlWord, |
convertWords(takeAt(valueof(KeyRegisterBase),readVReg(interfaceRegisters)))); |
loadState <= Load; |
loadCount <= 0; |
end |
else |
begin |
interfaceRegisters[incomingCommands.first.regTag] <= incomingCommands.first.payload; |
end |
endrule |
|
rule processRead(incomingCommands.first.command == Read); |
incomingCommands.deq; |
|
// This is a bit ugly, and we should possibly fix it. |
if(fromInteger(valueof(CompressionFunctionStatus)) == incomingCommands.first.regTag) |
begin |
outputFIFO.enq(fromInteger(valueof(MD6CommunicationConstant))|zeroExtend(compressionFunction.status)); |
end |
else |
begin |
outputFIFO.enq(fromInteger(valueof(MD6CommunicationConstant))|zeroExtend((interfaceRegisters[incomingCommands.first.regTag]))); |
end |
|
endrule |
|
|
|
|
// Probably should handle non-fitting burst sizes. But, don't have to |
// for now. |
if(valueof(TotalRegisters) != 47) |
begin |
error("Total Registers: %d\n",valueof(TotalRegisters)); |
end |
|
if(valueof(MD6_b)%valueof(MD6WordsPerBurst) != 0) |
begin |
error("MD6_b:%d not divisible by MD6WordsPerBurst:%d",valueof(MD6_b), valueof(MD6WordsPerBurst)); |
end |
|
if(valueof(MD6_c)%valueof(MD6WordsPerBurst) != 0) |
begin |
error("MD6_c:%d not divisible by MD6WordsPerBurst:%d",valueof(MD6_c), valueof(MD6WordsPerBurst)); |
end |
|
rule issueLoads(loadState == Load); |
if(loadCount + 1 == fromInteger(valueof(MD6_b)/valueof(MD6WordsPerBurst))) |
begin |
loadState <= Idle; |
storeState <= Store; |
storeCount <= 0; |
end |
loadCount <= loadCount + 1; |
BlockAddr refAddr = truncateLSB({interfaceRegisters[valueof(SourceRegisterBase)+1], |
interfaceRegisters[valueof(SourceRegisterBase)]}) |
+ (zeroExtend(loadCount) << (valueof(TLog#(WordsPerBurst)))); |
|
plbMaster.plbMasterCommandInput.put(tagged LoadPage refAddr); |
endrule |
|
|
|
rule issueStores(storeState == Store); |
if(storeCount + 1 == fromInteger(valueof(MD6_c)/valueof(MD6WordsPerBurst))) |
begin |
storeState <= Idle; |
end |
storeCount <= storeCount + 1; |
|
BlockAddr refAddr = truncateLSB({interfaceRegisters[valueof(DestinationRegisterBase)+1], |
interfaceRegisters[valueof(DestinationRegisterBase)]}) |
+ (zeroExtend(storeCount) << (valueof(TLog#(WordsPerBurst)))); |
|
plbMaster.plbMasterCommandInput.put(tagged StorePage refAddr); |
endrule |
|
interface plbMasterWires = plbMaster.plbMasterWires; |
interface bramInitiatorWires = feeder.bramInitiatorWires; |
|
endmodule |
/MD6Engine.h
0,0 → 1,38
#ifndef MD6_ENGINE_H |
#define MD6_ENGINE_H |
#include"md6.h" |
|
|
#define SHORT_WIDTH |
|
//#if sizeof(short) != 2 |
// #error "Miss-sized short" |
//#endif |
|
typedef enum {Read=0,Write=1,} Command; |
typedef enum {RoundRegister = 0, |
TreeHeightRegister = 1, |
LastCompressionRegister = 2, |
PaddingBitsRegister = 3, |
KeyLengthRegister = 4, |
DigestLengthRegister = 5, |
CompressionFunctionStatus = 6, |
KeyRegisterBase = 7, |
IdentifierRegisterBase = KeyRegisterBase + md6_k*(md6_w/16), |
SourceRegisterBase = IdentifierRegisterBase + md6_u*(md6_w/16), |
DestinationRegisterBase = SourceRegisterBase + 2, |
TotalRegisters = DestinationRegisterBase + 2 } RegisterAddr; |
|
|
|
/*int MD6Send(Command command, |
RegisterAddr reg, |
short payload); |
|
int MD6Receive(short * payload);*/ |
|
int MD6Write(RegisterAddr reg, short payload); |
|
int MD6Read(RegisterAddr reg, short *payload); |
|
#endif |
/MD6Driver.c
0,0 → 1,164
#include "md6.h" |
#include "MD6Engine.h" |
#include "timer.h" |
|
#ifdef DEBUG |
int writeCheck(RegisterAddr reg, short data); |
int readCheck(RegisterAddr reg, short data); |
#endif |
|
#undef DEBUG |
|
#define EVER ;; |
|
//int checkHash(md6_word *src, md6_word *dest, md6_word *uniqueID, |
// md6_word *tree_height, md6_word *last_op, |
// md6_word *padding_bits); |
#ifdef DEBUG |
inline int writeCheck(RegisterAddr reg, short data) { |
short temp; |
if(MD6Write(reg, data) < 0) { |
xil_printf("Failed to write %s\r\n", registerAddrToString(reg)); |
return -1; |
} |
|
return readCheck(reg,data); |
} |
#else |
int (*writeCheck) (RegisterAddr,short) = MD6Write; |
#endif |
|
inline int readCheck(RegisterAddr reg, short data) { |
short temp; |
if(MD6Read(reg, &temp) < 0) { |
xil_printf("Failed to read %s\r\n",registerAddrToString(reg)); |
return -1; |
} else if(temp != data) { |
xil_printf("%s == %x, expect %x\r\n",registerAddrToString(reg),temp,data); |
return -1; |
} |
return 0; |
} |
|
int startHash(md6_word *src, md6_word *dest, md6_word *uniqueID, |
md6_word *key, md6_word *tree_height, md6_word *last_op, |
md6_word *padding_bits, md6_word *digest_length) { |
short sent_value; |
int spins = 0; |
long long start, finish; |
int i; |
#ifdef DEBUG |
xil_printf("src: %x dest: %x \r\n", src, dest); |
#endif |
sent_value = ((int)src) & 0xffff; |
//Check that the compressor is turned off |
// if(readChseck(CompressionFunctionStatus,0)){ |
// return 0; |
// } |
|
if(writeCheck(SourceRegisterBase, sent_value) < 0) { |
return -1; |
} |
|
sent_value = ((int)src >>16) & 0xffff; |
if(writeCheck(SourceRegisterBase + 1, sent_value) < 0) { |
return -1; |
} |
|
sent_value = ((int)dest) & 0xffff; |
if(writeCheck(DestinationRegisterBase, sent_value) < 0) { |
return -1; |
} |
|
sent_value = ((int)dest >>16) & 0xffff; |
if(writeCheck(DestinationRegisterBase + 1, sent_value) < 0) { |
return -1; |
} |
|
// write out uniqueID |
for(i = 0; i < md6_u*md6_w/16; i++) { |
sent_value = ( (uniqueID[i>>2]) >> ((i&0x3)*16) ) & 0xffff; |
writeCheck(IdentifierRegisterBase+i,sent_value); |
} |
|
// write out key |
for(i = 0; i < md6_k*md6_w/16; i++) { |
sent_value = ( (key[i>>2]) >> ((i&0x3)*16) ) & 0xffff; |
writeCheck(KeyRegisterBase+i,sent_value); |
} |
|
sent_value = *tree_height & 0xffff; |
if(writeCheck(TreeHeightRegister, sent_value) < 0) { |
return -1; |
} |
|
sent_value = *last_op & 0xffff; |
if(writeCheck(LastCompressionRegister, sent_value) < 0) { |
return -1; |
} |
|
sent_value = *padding_bits & 0xffff; |
if(writeCheck(PaddingBitsRegister, sent_value) < 0) { |
return -1; |
} |
//XXXX this must be fixed at some point. |
sent_value = md6_k; |
if(writeCheck(KeyLengthRegister, sent_value) < 0) { |
return -1; |
} |
|
sent_value = 0; |
if(writeCheck(RoundRegister, sent_value) < 0) { |
return -1; |
} |
|
sent_value = (short)*digest_length & 0xffff; |
if(writeCheck(DigestLengthRegister, sent_value) < 0) { |
return -1; |
} |
|
#ifdef DEBUG |
for(i = 0; i < TotalRegisters; i++) { |
MD6Read(i,&sent_value); |
xil_printf("Reg[%d]: %4x ", i, sent_value); |
if(i%4==3) { |
printf("\r\n"); |
} |
} |
printf("\r\n"); |
#endif |
// md6_word *src, md6_word *dest, md6_word *uniqueID, |
// md6_word *tree_height, md6_word *last_op, |
// md6_word *padding_bits |
// this check could possibly fail |
start = ts_get_ll(); |
if(MD6Write(CompressionFunctionStatus,1)<0) { |
xil_printf("Failed to start Compression Function\r\n"); |
return -1; |
} |
|
|
|
|
for(EVER) { |
if(MD6Read(CompressionFunctionStatus, &sent_value) < 0) { |
xil_printf("Failed to read Compression Function Status spins: %d, %d\r\n",spins,CompressionFunctionStatus); |
return -1; |
} |
|
if(sent_value == 0) { |
finish = ts_get_ll(); |
xil_printf("Time kernel: %d %d\r\n", (int)(finish-start),ts_elapse_ns(start,finish)); |
break; |
} |
|
spins++; |
if(spins%1000000 == 0) { |
xil_printf("Compression Function Timeout, status: %d", sent_value); |
break; |
} |
} |
|
} |
|
|
/MD6Driver.h
0,0 → 1,16
#ifndef MD6_ENGINE_H |
|
#include "md6.h" |
#include "MD6Engine.h" |
|
int checkHash(md6_word *src, md6_word *dest, md6_word *uniqueID, |
md6_word *key, md6_word *tree_height, md6_word *last_op, |
md6_word *padding_bits, md6_word *digest_length); |
|
// this function expects src to be laid out 63:0 and writes dest 15:0 |
// These will be word reversed. |
int startHash(md6_word *src, md6_word *dest, md6_word *uniqueID, |
md6_word *key, md6_word *tree_height, md6_word *last_op, |
md6_word *padding_bits, md6_word *digest_length); |
|
#endif |
/MD6Engine.c
0,0 → 1,65
#include "md6.h" |
#include "MD6Engine.h" |
#include "cLib.h" |
|
#define MD6CommunicationConstant 0xC0000 |
|
inline int MD6Send(Command command, RegisterAddr reg, short payload) { |
int command_bits =(int)(((command & 0x1) << 31) | ((reg & 0x3fff) << 16) | ((payload & 0xffff) << 0)); |
return putValue(command_bits); |
} |
|
inline int MD6Receive(short *payload) { |
int resp; |
int value = getResponse(&resp); |
if(MD6CommunicationConstant ^ (resp & 0xFFFF0000)) { |
xil_printf("Communication may be corrupt\r\n"); |
} |
*payload = (short) resp; |
return value; |
} |
|
inline int MD6Write(RegisterAddr reg, short payload) { |
return MD6Send(Write, reg, payload); |
} |
|
inline int MD6Read(RegisterAddr reg, short *payload) { |
if(MD6Send(Read, reg, 0) < 0) { |
return -1; |
} |
return MD6Receive(payload); |
} |
|
/*typedef enum {RoundRegister = 0, |
TreeHeightRegister = 1, |
LastCompressionRegister = 2, |
PaddingBitsRegister = 3, |
KeyLengthRegister = 4, |
DigestLengthRegister = 5, |
CompressionFunctionStatus = 6, |
KeyRegisterBase = 7, |
IdentifierRegisterBase = KeyRegisterBase + md6_k*(md6_w/16), |
SourceRegisterBase = IdentifierRegisterBase + md6_u*(md6_w/16), |
DestinationRegisterBase = SourceRegisterBase + 2, |
TotalRegisters = DestinationRegisterBase + 2 } RegisterAddr;*/ |
|
char *registerAddrToString(RegisterAddr reg) { |
switch(reg) { |
case RoundRegister: return "RoundRegister"; |
case TreeHeightRegister: return "TreeHeightRegister"; |
case PaddingBitsRegister: return "PaddingBitsRegister"; |
case KeyLengthRegister: return "KeyLengthRegister"; |
case DigestLengthRegister: return "DigestLengthRegister"; |
case KeyRegisterBase: return "KeyRegisterBase"; |
case IdentifierRegisterBase: return "IdentifierRegisterBase"; |
case IdentifierRegisterBase + 1: return "IdentifierRegisterBase+1"; |
case IdentifierRegisterBase + 2: return "IdentifierRegisterBase+2"; |
case IdentifierRegisterBase + 3: return "IdentifierRegisterBase+3"; |
case CompressionFunctionStatus: return "CompressionFunctionStatus"; |
case SourceRegisterBase: return "SourceRegisterBase"; |
case SourceRegisterBase + 1: return "SourceRegisterBase + 1"; |
case DestinationRegisterBase: return "DestinationRegisterBase"; |
case DestinationRegisterBase + 1: return "DestinationRegisterBase + 1"; |
default: return "Uknown Register"; |
} |
} |