OpenCores
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/src/grpSd/unitSdCardModel/src
    from Rev 149 to Rev 150
    Reverse comparison

Rev 149 → Rev 150

/SdData.sv File deleted
/SdBusTrans.sv
1,17 → 1,24
`ifndef SDBUSTRANS_SV
`define SDBUSTRANS_SV
 
`include "SdDataBlock.sv"
 
const logic cSdStartbit = 0;
const logic cSdEndbit = 1;
 
typedef logic SdBusTransData[$];
 
virtual class SdBusTrans;
class SdBusTrans;
 
SdDataBlock DataBlocks[];
bit SendBusy = 0;
 
virtual function SdBusTransData packToData();
endfunction
 
virtual function void unpackFromData(ref SdBusTransData data);
endfunction
 
endclass
 
class SdBusTransToken extends SdBusTrans;
/SdBFM-impl.sv
1,7 → 1,7
`ifndef SDBFMIMPL_SV
`define SDBFMIMPL_SV
 
function SdBFM::new(virtual ISdCard card);
function SdBFM::new(virtual ISdBus card);
this.ICard = card;
this.Log = new;
this.Sem = new(1);
15,9 → 15,7
StopAfter = AfterCount;
endfunction
 
task SdBFM::send(input SdBusTrans token);
this.Sem.get(1);
task SdBFM::sendCmd(inout SdBusTransData data);
// startbit
@ICard.cb;
ICard.cb.Cmd <= cSdStartbit;
24,7 → 22,6
 
// data
begin
SdBusTransData data = token.packToData();
 
foreach(data[i]) begin
@ICard.cb;
39,7 → 36,95
 
@ICard.cb;
ICard.cb.Cmd <= 'z;
waitUntilReady();
endtask
 
task SdBFM::sendAllDataBlocks(SdDataBlock blocks[]);
foreach(blocks[i]) begin
sendDataBlock(blocks[i]);
waitUntilReady();
end
endtask
 
task SdBFM::waitUntilReady();
repeat (8) @ICard.cb;
endtask
 
task SdBFM::sendDataBlock(SdDataBlock block);
if (Mode == standard) sendStandardDataBlock(block.data);
else sendWideDataBlock(block.data);
endtask
 
task SdBFM::sendStandardDataBlock(logic data[$]);
data.push_front(0); // startbit
CrcOnContainer(data);
data.push_back(1); // endbit
 
foreach(data[i]) begin
@ICard.cb;
ICard.cb.Data[0] <= data[i];
end
 
@ICard.cb;
ICard.cb.Data <= 'z;
endtask
 
task SdBFM::sendWideDataBlock(logic data[$]);
logic dat0[$];
logic dat1[$];
logic dat2[$];
logic dat3[$];
 
for (int i = 0; i < data.size(); i+=4) begin
dat3.push_back(data[i]);
dat2.push_back(data[i+1]);
dat1.push_back(data[i+2]);
dat0.push_back(data[i+3]);
end
CrcOnContainer(dat0);
CrcOnContainer(dat1);
CrcOnContainer(dat2);
CrcOnContainer(dat3);
 
@ICard.cb;
ICard.cb.Data <= 0;
 
for(int i = 0; i < dat0.size(); i++) begin
@ICard.cb;
ICard.cb.Data <= (dat3[i]<<3) + (dat2[i] <<2) + (dat1[i] <<1) + dat0[i];
end
@ICard.cb;
ICard.cb.Data <= 0;
 
@ICard.cb;
ICard.cb.Data <= 'z;
endtask
 
task SdBFM::sendBusy();
@ICard.cb;
// 10 busy cycles
ICard.cb.Data[0] <= 0;
repeat (10) @ICard.cb;
ICard.cb.Data[0] <= 1;
 
@ICard.cb;
ICard.cb.Data <= 'z;
endtask
 
task SdBFM::send(input SdBusTrans token);
SdBusTransData data;
this.Sem.get(1);
data = token.packToData();
if (data.size() > 0) sendCmd(data);
if (token.DataBlocks.size() > 0) sendAllDataBlocks(token.DataBlocks);
else if (token.SendBusy == 1) sendBusy();
this.Sem.put(1);
endtask
 
73,9 → 158,54
begin
this.Log.error("Received invalid endbit during SdBFM.receive.\n");
end
endtask
 
task SdBFM::receiveDataBlock(output SdDataBlock block);
ICard.cb.Data <= 'bzzzz;
 
if (Mode == wide) wait (ICard.cb.Data == 'b0000);
else wait (ICard.cb.Data[0] == '0);
 
recvDataBlock(block);
endtask
 
task SdBFM::recvDataBlock(output SdDataBlock block);
if (Mode == standard) recvStandardDataBlock(block);
else recvWideDataBlock(block);
endtask
 
task SdBFM::recvStandardDataBlock(output SdDataBlock block);
Log.error("recvStandardDataBlock not implemented");
endtask
 
task SdBFM::recvWideDataBlock(output SdDataBlock block);
aCrc16 crc[4];
block = new();
 
$display("Startbits: %t", $time);
for (int j = 0; j <= 512*2; j++) begin
@ICard.cb;
for(int i = 0; i < 4; i++) begin
block.data.push_back(ICard.cb.Data[i]);
end
end
 
// crc
for (int j = 0; j < 16; j++) begin
@ICard.cb;
for(int i = 0; i < 4; i++) begin
crc[i] = ICard.cb.Data[i];
end
end
 
// TODO: check crc
 
// end bits
@ICard.cb;
$display("Endbits: %h, %t", ICard.cb.Data, $time);
assert(ICard.cb.Data == 'b1111);
endtask
 
task SdBFM::receiveOrSend();
if(ICard.cb.Cmd == cSdStartbit) begin
SdBusTransToken token;
/SdBFM.sv
8,7 → 8,7
`ifndef SDBFM_SV
`define SDBFM_SV
 
`include "SdCmdInterface.sv"
`include "SdBusInterface.sv"
`include "Crc.sv"
`include "Logger.sv"
`include "SDCommandArg.sv"
15,28 → 15,44
`include "SdBusTrans.sv"
 
typedef mailbox #(SdBusTrans) SdBfmMb;
typedef enum {
standard,
wide
} Mode_t;
 
class SdBFM;
 
virtual ISdCard.card ICard;
virtual ISdBus.card ICard;
SdBfmMb ReceivedTransMb;
SdBfmMb SendTransMb;
local semaphore Sem;
local Logger Log;
local int StopAfter = -1;
Mode_t Mode;
extern function new(virtual ISdBus card);
 
extern function new(virtual ISdCard card);
 
extern task start(); // starts a thread for receiving and sending via mailboxes
extern function stop(int AfterCount); // stop the thread
 
extern task send(input SdBusTrans token);
extern task sendBusy();
extern task receive(output SdBusTransToken token);
extern task receiveDataBlock(output SdDataBlock block);
extern task waitUntilReady();
 
extern local task sendCmd(inout SdBusTransData data);
extern local task sendAllDataBlocks(SdDataBlock blocks[]);
extern local task sendDataBlock(SdDataBlock block);
extern local task sendStandardDataBlock(logic data[$]);
extern local task sendWideDataBlock(logic data[$]);
extern local task recvDataBlock(output SdDataBlock block);
extern local task recvStandardDataBlock(output SdDataBlock block);
extern local task recvWideDataBlock(output SdDataBlock block);
extern local task recv(output SdBusTransToken token);
extern local task receiveOrSend();
extern local task run();
 
local semaphore Sem;
local Logger Log;
local int StopAfter = -1;
endclass
 
`include "SdBFM-impl.sv";
/SdDataBlock.sv
0,0 → 1,29
//
// file: SdData.sv
// author: Rainer Kastl
//
// Class for sending and receiving data (SD spec 2.00)
//
 
`ifndef SDDATA
`define SDDATA
typedef enum {
usual,
widewidth
} DataMode_t;
 
function automatic void CrcOnContainer(ref logic data[$]);
aCrc16 crc = 0;
crc = calcCrc16(data);
 
for (int i = 15; i >= 0; i--)
data.push_back(crc[i]);
endfunction
 
class SdDataBlock;
DataMode_t Mode;
logic data[$];
endclass
 
`endif
/SdCardModel.sv
13,13 → 13,11
 
`include "Crc.sv";
`include "SdCommand.sv";
`include "SdData.sv";
`include "SdBFM.sv";
`include "Logger.sv";
 
class SDCard;
local SdBFM bfm;
local virtual ISdCard.card ICard;
local SDCardState state;
local RCA_t rca;
local logic CCS;
27,8 → 25,6
local DataMode_t datamode;
local Logger log;
 
local event CmdReceived, InitDone;
 
local rand int datasize; // ram addresses = 2^datasize - 1; 512 byte blocks
constraint cdatasize {datasize > 1; datasize <= 32;}
 
38,12 → 34,9
this.ram = new[2^(datasize-1)];
endfunction
 
function new(virtual ISdCard CardInterface, event CmdReceived, event InitDone);
ICard = CardInterface;
bfm = new(CardInterface);
function new(SdBFM bfm);
this.bfm = bfm;
state = new();
this.CmdReceived = CmdReceived;
this.InitDone = InitDone;
this.CCS = 1;
rca = 0;
mode = standard;
61,7 → 54,6
SDOCR ocr;
SDCommandR6 rcaresponse;
logic data[$];
SdData sddata;
SdBusTransToken token;
 
log.note("Expecting CMD0");
156,21 → 148,19
this.bfm.receive(token);
assert(token.id == cSdCmdSendSCR);
 
// respond with R1
// respond with R1 and dummy SCR
response = new(cSdCmdSendSCR, state);
this.bfm.send(response);
 
repeat(2) @ICard.cb;
 
response.DataBlocks = new[1];
response.DataBlocks[0] = new();
// send dummy SCR
for (int i = 0; i < 64; i++)
data.push_back(0);
response.DataBlocks[0].data.push_back(0);
data[63-50] = 1;
data[63-48] = 1;
response.DataBlocks[0].data[63-50] = 1;
response.DataBlocks[0].data[63-48] = 1;
 
sddata = new(standard, widewidth);
sddata.send(ICard, data);
this.bfm.send(response);
 
// expect ACMD6
recvCMD55(rca);
182,7 → 172,7
response = new(cSdCmdSetBusWidth, state);
this.bfm.send(response);
 
sddata.mode = wide;
this.bfm.Mode = wide;
mode = wide;
 
// expect CMD6
190,18 → 180,18
this.bfm.receive(token);
assert(token.id == cSdCmdSwitchFuntion);
assert(token.arg == 'h00FFFFF1);
this.bfm.send(response);
 
// send status data structure
data = {};
response.DataBlocks = new[1];
response.DataBlocks[0] = new();
for (int i = 0; i < 512; i++)
data.push_back(0);
response.DataBlocks[0].data.push_back(0);
 
data[511-401] = 1;
data[511-376] = 1;
sddata.send(ICard, data);
response.DataBlocks[0].data[511-401] = 1;
response.DataBlocks[0].data[511-376] = 1;
 
this.bfm.send(response);
 
// expect CMD6 with set
log.note("Expect CMD6 with set");
this.bfm.receive(token);
209,16 → 199,6
assert(token.arg == 'h80FFFFF1);
this.bfm.send(response);
 
// send status data structure
data = {};
for (int i = 0; i < 512; i++)
data.push_back(0);
 
data[511-401] = 1;
data[511-376] = 1;
sddata.send(ICard, data);
 
// switch to 50MHz
// expect CMD13
log.note("Expect CMD13");
228,8 → 208,6
response = new(cSdCmdSendStatus, state);
this.bfm.send(response);
 
-> InitDone;
 
endtask
 
task run();
253,9 → 231,7
 
task read(SdBusTransToken token);
SDCommandR1 response;
logic data[$];
logic[31:0] addr;
SdData sddata = new(mode, usual);
 
// expect Read
assert(token.id == cSdCmdReadSingleBlock);
262,48 → 238,48
addr = token.arg[0];
assert(addr < ram.size());
response = new(cSdCmdReadSingleBlock, state);
this.bfm.send(response);
 
data = {};
response.DataBlocks = new[1];
response.DataBlocks[0] = new();
for (int i = 0; i < 512; i++) begin
for (int j = 7; j >= 0; j--) begin
data.push_back(ram[addr][i*8 + j]);
response.DataBlocks[0].data.push_back(ram[addr][i*8 + j]);
end
end
 
sddata.send(ICard, data);
this.bfm.send(response);
endtask
 
task write(SdBusTransToken token);
SDCommandR1 response;
SdData sddata = new(this.mode, widewidth);
logic rddata[$];
SdDataBlock rdblock;
logic[31:0] addr;
 
// expect Write
assert(token.id == cSdCmdWriteSingleBlock);
addr = token.arg[0];
addr = token.arg;
assert(addr < ram.size());
response = new(cSdCmdWriteSingleBlock, state);
this.bfm.send(response);
 
// recv data
sddata.recv(ICard, rddata);
$display("rddata: %p", rddata);
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
ram[addr][i * 8 + j] = rddata.pop_front();
ram[addr][i * 8 + j] = rdblock.data.pop_front();
end
end
 
repeat (8) @ICard.cb;
sddata.sendBusy(ICard);
 
this.bfm.waitUntilReady();
this.bfm.sendBusy();
$display("Ram at write address: %h", ram[addr]);
 
endtask
327,8 → 303,8
 
class NoSDCard extends SDCard;
 
function new(virtual ISdCard CardInterface, event CmdReceived, event InitDone);
super.new(CardInterface, CmdReceived, InitDone);
function new(SdBFM bfm);
super.new(bfm);
endfunction
 
task automatic init();
/SdBusInterface.sv
0,0 → 1,26
//
// file: ../../unitSdVerificationTestbench/src/SdCmdInterface.sv
// author: Rainer Kastl
//
// Interface for the SdCmd entity
//
 
`ifndef SDBUSINTERFACE_SV
`define SDBUSINTERFACE_SV
 
interface ISdBus;
wire Cmd;
logic SClk;
wire[3:0] Data;
 
clocking cb @(posedge SClk);
inout Cmd;
inout Data;
endclocking
 
modport card (clocking cb);
 
endinterface
 
`endif
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.