URL
https://opencores.org/ocsvn/sdhc-sc-core/sdhc-sc-core/trunk
Subversion Repositories sdhc-sc-core
Compare Revisions
- This comparison shows the changes necessary to convert path
/sdhc-sc-core/trunk
- from Rev 159 to Rev 160
- ↔ Reverse comparison
Rev 159 → Rev 160
/src/grpSd/unitSdCardModel/src/RamAction.sv
9,6 → 9,12
kinds Kind; |
int Addr; |
DataBlock Data; |
|
function new(kinds kind = Read, int addr = 0, DataBlock data = {}); |
Kind = kind; |
Addr = addr; |
Data = data; |
endfunction |
endclass |
|
typedef mailbox #(RamAction) RamActionMb; |
/src/grpSd/unitSdCardModel/src/SdCardModel.sv
17,25 → 17,62
`include "Logger.sv"; |
`include "RamAction.sv"; |
|
class RamModel; |
local bit[0:511][7:0] data[]; |
RamActionMb RamActionOutMb; |
|
function new(int size); |
data = new[size]; |
endfunction |
|
function int size(); |
return data.size(); |
endfunction |
|
task getDataBlock(logic[31:0] addr, output SdDataBlock block); |
RamAction action = new(RamAction::Read, addr, data[addr]); |
block = new(); |
|
for (int i = 0; i < 512; i++) begin |
for (int j = 7; j >= 0; j--) begin |
block.data.push_back(data[addr][i][j]); |
end |
end |
|
RamActionOutMb.put(action); |
endtask |
|
task setDataBlock(logic[31:0] addr, SdDataBlock block); |
for (int i = 0; i < 512; i++) begin |
for (int j = 7; j >= 0; j--) begin |
data[addr][i][j] = block.data.pop_front(); |
end |
end |
|
begin |
RamAction action = new(RamAction::Write, addr, data[addr]); |
RamActionOutMb.put(action); |
end |
endtask |
|
endclass |
|
class SdCardModel; |
|
RamActionMb RamActionOutMb; |
SdBfmMb SdTransOutMb; |
SdBfmMb SdTransInMb; |
|
SdBFM bfm; |
local SdCardModelState state; |
local SdCardModelState state = new(); |
local RCA_t rca; |
local logic CCS; |
local Mode_t mode; |
local DataMode_t datamode; |
local Logger log; |
local Logger log = new(); |
RamModel ram; |
|
|
//local rand int datasize; // ram addresses = 2^datasize - 1; 512 byte blocks |
//constraint cdatasize {datasize == 32;} |
|
local bit[0:511][7:0] ram[]; |
|
/*function void post_randomize() ; |
this.ram = new[datasize]; |
42,13 → 79,10
endfunction*/ |
|
function new(); |
//this.bfm = bfm; |
state = new(); |
this.CCS = 1; |
rca = 0; |
mode = standard; |
log = new(); |
ram = new[100]; |
ram = new(100); |
endfunction |
|
task start(); |
254,16 → 288,10
assert(addr <= ram.size()) else log.error("Read outside of available RAM"); |
response = new(cSdCmdReadSingleBlock, state); |
response.DataBlocks = new[1]; |
response.DataBlocks[0] = new(); |
|
//$display("Ram before read (%h): %h", addr, ram[addr]); |
ram.getDataBlock(addr, response.DataBlocks[0]); |
|
for (int i = 0; i < 512; i++) begin |
for (int j = 7; j >= 0; j--) begin |
response.DataBlocks[0].data.push_back(ram[addr][i][j]); |
end |
end |
|
this.bfm.send(response); |
endtask |
|
281,28 → 309,11
|
// recv data |
this.bfm.receiveDataBlock(rdblock); |
//$display("rddata: %p", rdblock.data); |
//$display("datasize: %h", datasize); |
//$display("Address (token): %h", token.arg); |
//$display("Address: %h", addr); |
|
// write into ram |
for (int i = 0; i < 512; i++) begin |
for (int j = 7; j >= 0; j--) begin |
//$display("rd_front: %d", rdblock.data[0:7]); |
ram[addr][i][j] = rdblock.data.pop_front(); |
end |
end |
|
ram.setDataBlock(addr, rdblock); |
|
this.bfm.waitUntilReady(); |
this.bfm.sendBusy(); |
|
//$display("Ram after write (%h): %h", addr, ram[addr]); |
/*$display("Ram after write (%h):", addr); |
for(int i = 0; i < 512; i++) begin |
$display("idx %d: %d", i, ram[addr][i]); |
end*/ |
|
endtask |
|
task recvCMD55(RCA_t rca); |
/src/grpSd/unitSdWbSlave/src/SdWbSlave-Rtl-a.vhdl
164,8 → 164,8
NxR.WbState <= ClassicWrite; |
|
if (iWbDat.Sel = "1") then |
if (iWbDat.Adr = cOperationAddr and |
R.SdIntState = newOperation) then |
if (iWbDat.Adr = cOperationAddr or iWbDat.Adr = cStartAddrAddr or iWbDat.Adr = cEndAddrAddr) and |
R.SdIntState = newOperation then |
-- insert waitstates until we can notify the SdController again |
|
NxR.oWbCtrl.Ack <= cInactivated; |
/src/grpSd/unitSdVerificationTestbench/src/SdVerificationTestbench.sv
32,7 → 32,7
harness.Card = card; |
|
harness.start(); |
#2ms; |
#20ms; |
|
log.terminate(); |
end |
/src/grpSd/unitSdVerificationTestbench/src/Harness.sv
54,7 → 54,7
TransBfm.WbTransOutMb = new(1); |
WbBfm.TransOutMb = new(1); |
TransBfm.SdTransOutMb = new(1); |
Card.RamActionOutMb = new(1); |
Card.ram.RamActionOutMb = new(1); |
TransFunc.ExpectedResultOutMb = new(1); |
Card.SdTransOutMb = new(1); |
Card.SdTransInMb = new(1); |
68,7 → 68,7
WbBfm.TransInMb = TransBfm.WbTransOutMb; |
TransBfm.WbTransInMb = WbBfm.TransOutMb; |
Checker.SdTransInMb = TransBfm.SdTransOutMb; |
Checker.RamActionInMb = Card.RamActionOutMb; |
Checker.RamActionInMb = Card.ram.RamActionOutMb; |
Checker.ExpectedResultInMb = TransFunc.ExpectedResultOutMb; |
SdBfm.SendTransMb = Card.SdTransOutMb; |
SdBfm.ReceivedTransMb = Card.SdTransInMb; |
/src/grpSd/unitSdVerificationTestbench/sim/wave.do
2,27 → 2,44
quietly WaveActivateNextPane {} 0 |
add wave -noupdate -format Logic /Testbed/CardInterface/Cmd |
add wave -noupdate -format Logic /Testbed/CardInterface/SClk |
add wave -noupdate -format Literal /Testbed/CardInterface/Data |
add wave -noupdate -format Literal -radix hexadecimal /Testbed/CardInterface/Data |
add wave -noupdate -format Logic /Testbed/IWbBus/ERR_I |
add wave -noupdate -format Logic /Testbed/IWbBus/RTY_I |
add wave -noupdate -format Logic /Testbed/IWbBus/CLK_I |
add wave -noupdate -format Logic /Testbed/IWbBus/RST_I |
add wave -noupdate -format Logic /Testbed/IWbBus/ACK_I |
add wave -noupdate -format Literal /Testbed/IWbBus/DAT_I |
add wave -noupdate -format Literal -radix hexadecimal /Testbed/IWbBus/DAT_I |
add wave -noupdate -format Logic /Testbed/IWbBus/CYC_O |
add wave -noupdate -format Literal /Testbed/IWbBus/ADR_O |
add wave -noupdate -format Literal /Testbed/IWbBus/DAT_O |
add wave -noupdate -format Logic /Testbed/IWbBus/SEL_O |
add wave -noupdate -format Literal -radix hexadecimal /Testbed/IWbBus/ADR_O |
add wave -noupdate -format Literal -radix hexadecimal /Testbed/IWbBus/DAT_O |
add wave -noupdate -format Logic /Testbed/IWbBus/STB_O |
add wave -noupdate -format Literal /Testbed/IWbBus/TGA_O |
add wave -noupdate -format Literal /Testbed/IWbBus/TGC_O |
add wave -noupdate -format Logic /Testbed/IWbBus/TGD_O |
add wave -noupdate -format Logic /Testbed/IWbBus/WE_O |
add wave -noupdate -format Logic /Testbed/IWbBus/LOCK_O |
add wave -noupdate -format Literal /Testbed/IWbBus/CTI_O |
add wave -noupdate -format Literal /Testbed/IWbBus/BTE_O |
add wave -noupdate -format Logic /Testbed/top/sdcontroller_inst/iclk |
add wave -noupdate -format Logic /Testbed/top/sdcontroller_inst/inresetasync |
add wave -noupdate -format Literal /Testbed/top/sdcontroller_inst/isdcmd |
add wave -noupdate -format Literal /Testbed/top/sdcontroller_inst/osdcmd |
add wave -noupdate -format Literal /Testbed/top/sdcontroller_inst/isddata |
add wave -noupdate -format Literal /Testbed/top/sdcontroller_inst/osddata |
add wave -noupdate -format Literal /Testbed/top/sdcontroller_inst/isdwbslave |
add wave -noupdate -format Literal /Testbed/top/sdcontroller_inst/osdwbslave |
add wave -noupdate -format Literal /Testbed/top/sdcontroller_inst/r |
add wave -noupdate -format Literal /Testbed/top/sdcontroller_inst/nextr |
add wave -noupdate -format Logic /Testbed/top/sdwbslave_inst/iclk |
add wave -noupdate -format Logic /Testbed/top/sdwbslave_inst/irstsync |
add wave -noupdate -format Literal /Testbed/top/sdwbslave_inst/iwbctrl |
add wave -noupdate -format Literal /Testbed/top/sdwbslave_inst/owbctrl |
add wave -noupdate -format Literal /Testbed/top/sdwbslave_inst/iwbdat |
add wave -noupdate -format Literal /Testbed/top/sdwbslave_inst/owbdat |
add wave -noupdate -format Literal /Testbed/top/sdwbslave_inst/icontroller |
add wave -noupdate -format Literal /Testbed/top/sdwbslave_inst/ocontroller |
add wave -noupdate -format Literal /Testbed/top/sdwbslave_inst/owritefifo |
add wave -noupdate -format Literal /Testbed/top/sdwbslave_inst/iwritefifo |
add wave -noupdate -format Literal /Testbed/top/sdwbslave_inst/oreadfifo |
add wave -noupdate -format Literal /Testbed/top/sdwbslave_inst/ireadfifo |
add wave -noupdate -format Literal /Testbed/top/sdwbslave_inst/r |
add wave -noupdate -format Literal /Testbed/top/sdwbslave_inst/nxr |
TreeUpdate [SetDefaultTree] |
WaveRestoreCursors {{Cursor 1} {2518 ns} 0} {{Cursor 2} {10084945 ns} 0} {{Cursor 3} {10085095 ns} 0} |
WaveRestoreCursors {{Cursor 1} {2496665 ns} 0} {{Cursor 2} {6033878 ns} 0} {{Cursor 3} {19999903 ns} 0} |
configure wave -namecolwidth 150 |
configure wave -valuecolwidth 100 |
configure wave -justifyvalue left |
37,4 → 54,4
configure wave -timeline 0 |
configure wave -timelineunits ns |
update |
WaveRestoreZoom {0 ns} {5875 ns} |
WaveRestoreZoom {2005 us} {4105 us} |
/src/grpSdVerification/unitSdCoreChecker/src/SdCoreChecker.sv
81,21 → 81,51
join_none |
endtask |
|
function void checkRamAction(RamAction actual, RamAction expected, DataBlock block); |
if (expected.Kind == RamAction::Write) begin |
if (actual.Kind != expected.Kind || |
actual.Addr != expected.Addr || |
actual.Data != expected.Data) begin |
|
string msg; |
$swrite(msg, "RamActions differ: %s%p%s%p%s%d%s%d%s%p%s%p", |
"\nactual kind ", actual.Kind, ", expected kind ", expected.Kind, |
"\nactual addr ", actual.Addr, ", expected addr ", expected.Addr, |
"\nactual data ", actual.Data, ", expected data ", expected.Data); |
Log.error(msg); |
|
end |
end else begin |
if (actual.Kind != expected.Kind || |
actual.Addr != expected.Addr || |
actual.Data != block) begin |
|
string msg; |
$swrite(msg, "RamActions differ: %s%p%s%p%s%d%s%d%s%p%s%p", |
"\nactual kind ", actual.Kind, ", expected kind ", expected.Kind, |
"\nactual addr ", actual.Addr, ", expected addr ", expected.Addr, |
"\nactual data ", actual.Data, ", expected data ", block); |
Log.error(msg); |
|
end |
end |
endfunction |
|
task run(); |
while (StopAfter != 0) begin |
ExpectedResult res; |
RamAction ram; |
RamAction ram[]; |
|
// get transactions |
ExpectedResultInMb.get(res); |
ram = new[res.RamActions.size()]; |
foreach(ram[i]) RamActionInMb.get(ram[i]); |
SdTransInMb.get(trans); |
|
//if (res.RamActions.size() > 0) RamActionInMb.get(ram); |
|
Log.warning("SdCoreChecker: RamActions not handled"); |
|
// update functional coverage |
SdCoreTransactions.sample(); |
|
// check transaction |
if (res.trans.compare(trans) == 1) begin |
string msg; |
Log.note("Checker: Transaction successful"); |
108,6 → 138,11
Log.error(msg); |
end |
|
// check data |
foreach(ram[i]) begin |
checkRamAction(ram[i], res.RamActions[i], trans.data[i]); |
end |
|
if (StopAfter > 0) StopAfter--; |
end |
|
/src/grpSdVerification/unitSdCoreTransaction/src/SdCoreTransaction.sv
13,6 → 13,8
rand int endAddr; |
rand DataBlock data[]; |
|
local int maxAddr = 31; |
|
constraint datablocks { |
if (kind == writeMultipleBlocks) { |
data.size() inside {[0:1000]}; |
27,8 → 29,8
kind == readSingleBlock || |
kind == writeSingleBlock; |
|
startAddr inside {[0:31]}; |
endAddr inside {[0:31]}; |
startAddr inside {[0:maxAddr]}; |
endAddr inside {[0:maxAddr]}; |
}; |
|
function SdCoreTransaction copy(); |
43,13 → 45,15
|
function string toString(); |
string s; |
$swrite(s, "kind: %p, addresses: %d, %d, data: %p", kind, startAddr, endAddr, data); |
$swrite(s, "kind: %p, addresses: %d, %d", kind, startAddr, endAddr); |
return s; |
endfunction |
|
// compare kind and addresses |
// NOTE: data has to be checked with other objects |
function bit compare(input SdCoreTransaction rhs); |
if (rhs.kind == this.kind && rhs.startAddr == this.startAddr && |
rhs.endAddr == this.endAddr && rhs.data == this.data) return 1; |
if (rhs.kind == this.kind && rhs.startAddr == this.startAddr) |
return 1; |
else return 0; |
endfunction |
|
58,24 → 62,16
class SdCoreTransactionSequence; |
|
rand SdCoreTransaction transactions[]; |
local const int size = 1000; |
|
function new(); |
transactions = new[100]; |
transactions = new[size]; |
foreach(transactions[i]) transactions[i] = new(); |
endfunction |
|
constraint randlength { |
transactions.size() > 0; |
transactions.size() <= 100; |
|
foreach(transactions[i]) { |
if (i % 2 == 0) { |
transactions[i].kind == SdCoreTransaction::writeSingleBlock; |
} else { |
transactions[i].kind == SdCoreTransaction::readSingleBlock; |
transactions[i].startAddr == transactions[i-1].startAddr; |
} |
} |
transactions.size() inside {[100:1000]}; |
transactions.size() < size; |
} |
|
endclass |
/src/grpSdVerification/unitSdCoreTransactionBFM/src/SdCoreTransactionBFM.sv
35,7 → 35,6
int j = 0; |
string msg; |
WbTransactionSequenceReadSingleBlock tmp = new(trans.startAddr, trans.endAddr); |
$swrite(msg, "Addresses: in: %h, %h, out: %h, %h", trans.startAddr, trans.endAddr, tmp.StartAddr, tmp.EndAddr); |
assert (tmp.randomize()) else Log.error("Randomizing WbTransactionSequence seq failed."); |
seq = tmp; |
|
51,10 → 50,10
|
// receive read data |
if (tr.Kind == WbTransaction::Read && tr.Addr == cReadDataAddr) begin |
trans.data[0][j++] = tr.Data[7:0]; |
trans.data[0][j++] = tr.Data[15:8]; |
trans.data[0][j++] = tr.Data[23:16]; |
trans.data[0][j++] = tr.Data[31:24]; |
trans.data[0][j++] = tr.Data[23:16]; |
trans.data[0][j++] = tr.Data[15:8]; |
trans.data[0][j++] = tr.Data[7:0]; |
end |
end |
|
/src/grpSdVerification/unitSdCoreTransactionBFM/src/WbTransactionWriteSingleBlock.sv
23,26 → 23,18
|
for (int i = 0; i < 512/4; i++) begin |
WbData temp = 0; |
temp = { >> {Datablock[i*4], Datablock[i*4+1], Datablock[i*4+2], Datablock[i*4+3]}}; |
temp = { >> {Datablock[i*4+3], Datablock[i*4+2], Datablock[i*4+1], Datablock[i*4+0]}}; |
Data.push_back(temp); |
end |
endfunction |
|
constraint WriteAddrFirst { |
transactions[0].Addr == cStartAddrAddr || |
transactions[0].Addr == cEndAddrAddr; |
transactions[2].Addr == cOperationAddr; |
transactions[1].Addr == cEndAddrAddr; |
transactions[1].Data == EndAddr; |
transactions[0].Addr == cStartAddrAddr; |
transactions[0].Data == StartAddr; |
|
if (transactions[0].Addr == cStartAddrAddr) { |
transactions[1].Addr == cEndAddrAddr; |
transactions[1].Data == EndAddr; |
transactions[0].Data == StartAddr; |
} else if (transactions[0].Addr == cEndAddrAddr) { |
transactions[1].Addr == cStartAddrAddr; |
transactions[0].Data == EndAddr; |
transactions[1].Data == StartAddr; |
} |
|
foreach(transactions[i]) { |
transactions[i].Kind == WbTransaction::Write; |
|
/src/grpSdVerification/unitSdCoreTransferFunction/src/SdCoreTransferFunction.sv
4,6 → 4,7
`include "SdCoreTransaction.sv"; |
`include "ExpectedResult.sv"; |
`include "Logger.sv"; |
`include "SdCardModel.sv"; |
|
class SdCoreTransferFunction; |
|
34,7 → 35,6
res.RamActions[0] = new(); |
res.RamActions[0].Kind = RamAction::Read; |
res.RamActions[0].Addr = transaction.startAddr; |
Log.note("TF: Handle data"); |
end |
|
SdCoreTransaction::writeSingleBlock: |
41,7 → 41,7
begin |
res.RamActions = new[1]; |
res.RamActions[0] = new(); |
res.RamActions[0].Kind = RamAction::Read; |
res.RamActions[0].Kind = RamAction::Write; |
res.RamActions[0].Addr = transaction.startAddr; |
res.RamActions[0].Data = transaction.data[0]; |
end |
/src/grpVerification/unitLogger/src/Logger.sv
11,6 → 11,7
class Logger; |
|
local static int errors = 0; |
local static int warnings = 0; |
|
function new(); |
endfunction |
23,6 → 24,7
function void warning(string msg); |
$write("Warning at %t: ", $time); |
$display(msg); |
warnings++; |
endfunction |
|
function void error(string msg); |
36,6 → 38,10
if (errors > 0) begin |
$display("%d errors.", errors); |
end |
|
if (warnings > 0) begin |
$display("%d warnings.", warnings); |
end |
endfunction |
|
endclass |