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
    /
    from Rev 119 to Rev 120
    Reverse comparison

Rev 119 → Rev 120

/sdhc-sc-core/trunk/src/grpSd/pkgSdWb/src/SdWb-p.vhdl
61,7 → 61,6
type aSdControllerToSdWbSlave is record
 
ReqOperationEdge : std_ulogic; -- Request a new OperationBlock
Done : std_ulogic;
ReadData : aData;
 
end record aSdControllerToSdWbSlave;
/sdhc-sc-core/trunk/src/grpSd/unitSdWbSlave/Files.tcl
2,4 → 2,8
Wishbone Wishbone
Sd SdWb}
 
set units {Sd SdWbSlave {Rtl}}
set units {Sd SdWbSlave {Rtl}
Sd SdWbSlaveWrapper {Rtl}}
 
set svtb {Sd SdWbSlave}
set top Testbed
/sdhc-sc-core/trunk/src/grpSd/unitSdWbSlave/src/SdWbSlave-Rtl-a.vhdl
9,7 → 9,7
 
architecture Rtl of SdWbSlave is
 
type aWbState is (idle, ClassicRead, ClassicWrite);
type aWbState is (idle, ClassicWrite, ClassicRead);
type aSdIntState is (idle, newOperation);
 
type aRegs is record
18,7 → 18,7
SdIntState : aSdIntState; -- state of the sd controller interface
OperationBlock : aOperationBlock; -- Operation for the SdController
ReqOperation : std_ulogic; -- Register for catching edges on the SdController ReqOperationEdge line
-- Register outputs
-- Register outputs
oWbDat : aSdWbSlaveDataOutput;
oWbCtrl : aWbSlaveCtrlOutput;
oController : aSdWbSlaveToSdController;
37,7 → 37,10
signal R, NxR : aRegs;
 
begin
oWbDat <= R.oWbDat;
oWbCtrl <= R.oWbCtrl;
oController <= R.oController;
 
WbStateReg : process (iClk, iRstSync)
begin
if (iClk'event and iClk = cActivated) then
61,81 → 64,78
case R.WbState is
when idle =>
if iWbCtrl.Cyc = cActivated and iWbCtrl.Stb = cActivated then
 
case iWbCtrl.Cti is
when cCtiClassicCycle =>
-- switch to ClassicRead or ClassicWrite
case iWbCtrl.We is
when cInactivated =>
NxR.WbState <= ClassicRead;
 
-- perform a ClassicRead
NxR.oWbCtrl.Ack <= cActivated;
NxR.WbState <= ClassicRead;
 
if (iWbDat.Sel = "1") then
case iWbDat.Adr is
when cOperationAddr =>
NxR.oWbDat.Dat <= R.OperationBlock.Operation;
 
when cStartAddrAddr =>
NxR.oWbDat.Dat <= R.OperationBlock.StartAddr;
 
when cEndAddrAddr =>
NxR.oWbDat.Dat <= R.OperationBlock.EndAddr;
 
when cReadDataAddr =>
-- read data from fifo
 
when others =>
report "Read to an invalid address" severity warning;
NxR.oWbCtrl.Err <= cActivated;
NxR.oWbCtrl.Ack <= cInactivated;
end case;
end if;
when cActivated =>
NxR.WbState <= ClassicWrite;
 
--perform a ClassicWrite
NxR.oWbCtrl.Ack <= cActivated;
NxR.WbState <= ClassicWrite;
 
if (iWbDat.Sel = "1" and
iWbDat.Adr = cOperationAddr and
R.SdIntState = newOperation) then
-- insert waitstates until we can notify the SdController again
 
NxR.oWbCtrl.Ack <= cInactivated;
NxR.WbState <= idle;
 
end if;
 
when others =>
report "iWbCtrl.We is invalid" severity warning;
end case;
 
when others => null;
end case;
 
end if;
 
when ClassicRead =>
assert (iWbCtrl.Cyc = cActivated) report
"Cyc deactivated mid cyclus" severity warning;
when ClassicRead =>
NxR.WbState <= idle;
 
NxR.oWbCtrl.Ack <= cActivated;
 
if (iWbDat.Sel = "1") then
case iWbDat.Adr is
when cOperationAddr =>
NxR.oWbDat.Dat <= R.OperationBlock.Operation;
 
when cStartAddrAddr =>
NxR.oWbDat.Dat <= R.OperationBlock.StartAddr;
 
when cEndAddrAddr =>
NxR.oWbDat.Dat <= R.OperationBlock.EndAddr;
 
when cReadDataAddr =>
-- read data from fifo
 
when others =>
report "Read to an invalid address" severity warning;
NxR.oWbCtrl.Err <= cActivated;
NxR.oWbCtrl.Ack <= cInactivated;
end case;
end if;
when ClassicWrite =>
NxR.WbState <= idle;
 
when ClassicWrite =>
assert (iWbCtrl.Cyc = cActivated) report
"Cyc deactivated mid cyclus" severity warning;
 
-- default state transition and output
 
NxR.oWbCtrl.Ack <= cActivated;
NxR.WbState <= idle;
 
if (iWbDat.Sel = "1") then
case iWbDat.Adr is
when cOperationAddr =>
if (R.SdIntState = idle) then
-- save operation and notify the SdController
 
NxR.OperationBlock.Operation <= iWbDat.Dat;
NxR.SdIntState <= newOperation;
NxR.OperationBlock.Operation <= iWbDat.Dat;
NxR.SdIntState <= newOperation;
 
else
-- insert waitstates until we can notify the SdController again
 
NxR.oWbCtrl.Ack <= cInactivated;
 
end if;
 
when cStartAddrAddr =>
 
NxR.OperationBlock.StartAddr <= iWbDat.Dat;
 
when cEndAddrAddr =>
146,11 → 146,13
-- put into fifo
 
when others =>
report "Read to an invalid address" severity warning;
report "Write to an invalid address" severity warning;
end case;
end if;
 
when others => null;
 
when others =>
report "Invalid state" severity error;
end case;
 
-- send operations to SdController
160,8 → 162,8
 
if (iController.ReqOperationEdge = cActivated) then
 
R.ReqOperation <= cActivated;
NxR.ReqOperation <= cActivated;
 
end if;
 
when newOperation =>
172,12 → 174,12
NxR.oController.AckOperationToggle <= not R.oController.AckOperationToggle;
 
-- go to idle state, the next request will come only after the SdController received this block
 
NxR.ReqOperation <= cInactivated;
NxR.SdIntState <= idle;
 
end if;
 
when others =>
report "Invalid state" severity error;
end case;
/sdhc-sc-core/trunk/src/grpSd/unitSdWbSlave/src/WishboneInterface.sv
0,0 → 1,46
//
// file: WishboneInterface.sv
// author: Copyright 2010: Rainer Kastl
//
// Description: Wishbone interface
//
 
interface WishboneInterface;
 
logic ERR_I;
logic RTY_I;
logic CLK_I = 1;
logic RST_I;
logic ACK_I;
logic [`cWishboneWidth-1 : 0] DAT_I;
 
logic CYC_O;
logic [6:4] ADR_O;
logic [`cWishboneWidth-1 : 0] DAT_O;
logic [`cWishboneWidth/`cWishboneWidth-1 : 0] SEL_O;
logic STB_O;
logic [`cWishboneWidth-1 : 0] TGA_O;
logic [`cWishboneWidth-1 : 0] TGC_O;
logic TGD_O;
logic WE_O;
logic LOCK_O;
aCTI CTI_O;
logic [1 : 0] BTE_O;
 
// Masters view of the interface
clocking cbMaster @(posedge CLK_I);
input ERR_I, RTY_I, ACK_I, DAT_I;
output CYC_O, ADR_O, DAT_O, SEL_O, STB_O, TGA_O, TGC_O, TGD_O, WE_O, LOCK_O, CTI_O, RST_I;
endclocking
modport Master (
input CLK_I, clocking cbMaster
);
 
// Slaves view of the interface
modport Slave (
input CLK_I, RST_I, CYC_O, ADR_O, DAT_O, SEL_O, STB_O, TGA_O, TGC_O, TGD_O, WE_O, LOCK_O, CTI_O,
output ERR_I, RTY_I, ACK_I, DAT_I
);
 
endinterface;
 
/sdhc-sc-core/trunk/src/grpSd/unitSdWbSlave/src/Wishbone-BFM.sv
0,0 → 1,218
//
// file: Wishbone-BFM.sv
// author: Copyright 2010: Rainer Kastl
//
// Description: Bus functional model for wishbone registered feedback
// Wishbone spec Revision B.3
//
 
class Wishbone;
 
virtual WishboneInterface.Master Bus;
 
function new(virtual WishboneInterface.Master Bus);
this.Bus = Bus;
endfunction
 
task Idle();
 
@(posedge this.Bus.CLK_I)
this.Bus.cbMaster.CYC_O <= cNegated;
this.Bus.cbMaster.ADR_O <= '{default: cDontCare};
this.Bus.cbMaster.DAT_O <= '{default: cDontCare};
this.Bus.cbMaster.SEL_O <= '{default: cDontCare};
this.Bus.cbMaster.STB_O <= cNegated;
this.Bus.cbMaster.TGA_O <= '{default: cDontCare};
this.Bus.cbMaster.TGC_O <= '{default: cDontCare};
this.Bus.cbMaster.TGD_O <= cDontCare;
this.Bus.cbMaster.WE_O <= cDontCare;
this.Bus.cbMaster.LOCK_O <= cNegated;
this.Bus.cbMaster.CTI_O <= '{default: cDontCare};
$display("%t : Bus idle.", $time);
 
endtask;
 
function void checkResponse();
 
// Analyse slave response
if (this.Bus.cbMaster.ERR_I == cAsserted) begin
$display("%t : MasterWrite: ERR_I asserted; Slave encountered an error.", $time);
end
if (this.Bus.cbMaster.RTY_I == cAsserted) begin
$display("%t : MasterWrite: RTY_I asserted; Retry requested.", $time);
end
 
endfunction;
 
task Read(logic [`cWishboneWidth-1 : 0] Address,
ref logic [`cWishboneWidth-1 : 0] Data,
input logic [`cWishboneWidth-1 : 0] TGA = '{default: cDontCare},
input logic [`cWishboneWidth-1 : 0] BankSelect = '{default: 1});
 
@(posedge this.Bus.CLK_I);
this.Bus.cbMaster.ADR_O <= Address;
this.Bus.cbMaster.TGA_O <= TGA;
this.Bus.cbMaster.WE_O <= cNegated;
this.Bus.cbMaster.SEL_O <= BankSelect;
this.Bus.cbMaster.CYC_O <= cAsserted;
this.Bus.cbMaster.TGC_O <= cAsserted;
this.Bus.cbMaster.STB_O <= cAsserted;
this.Bus.cbMaster.CTI_O <= ClassicCycle;
 
//$display("%t : MasterRead: Waiting for slave resonse", $time);
// Wait until slave responds
wait ((this.Bus.cbMaster.ACK_I == cAsserted)
|| (this.Bus.cbMaster.ERR_I == cAsserted)
|| (this.Bus.cbMaster.RTY_I == cAsserted));
 
checkResponse();
 
Data = this.Bus.cbMaster.DAT_I; // latch it before the CLOCK???
//$display("%t : Reading %h", $time, Data);
 
this.Bus.cbMaster.STB_O <= cNegated;
this.Bus.cbMaster.CYC_O <= cNegated;
@(posedge this.Bus.CLK_I);
 
endtask;
 
task BlockRead(logic [`cWishboneWidth-1 : 0] Address,
ref logic [`cWishboneWidth-1 : 0] Data[],
input logic [`cWishboneWidth-1 : 0] TGA = '{default: cDontCare},
input logic [`cWishboneWidth-1 : 0] BankSelect = '{default: 1});
 
foreach(Data[i]) begin
this.Bus.cbMaster.WE_O <= cNegated;
this.Bus.cbMaster.CYC_O <= cAsserted;
this.Bus.cbMaster.TGC_O <= cAsserted;
this.Bus.cbMaster.STB_O <= cAsserted;
this.Bus.cbMaster.LOCK_O <= cAsserted;
this.Bus.cbMaster.ADR_O <= Address+i;
this.Bus.cbMaster.TGA_O <= TGA;
this.Bus.cbMaster.SEL_O <= BankSelect;
this.Bus.cbMaster.CTI_O <= ClassicCycle;
@(posedge this.Bus.CLK_I);
 
//$display("%t : MasterRead: Waiting for slave response.", $time);
// Wait until slave responds
wait ((this.Bus.cbMaster.ACK_I == cAsserted)
|| (this.Bus.cbMaster.ERR_I == cAsserted)
|| (this.Bus.cbMaster.RTY_I == cAsserted));
 
checkResponse();
Data[i] = this.Bus.cbMaster.DAT_I;
//$display("%t : Reading %h", $time, Data[i]);
end
 
this.Bus.cbMaster.STB_O <= cNegated;
this.Bus.cbMaster.CYC_O <= cNegated;
this.Bus.cbMaster.LOCK_O <= cNegated;
@(posedge this.Bus.CLK_I);
 
endtask;
 
task Write(logic [`cWishboneWidth-1 : 0] Address,
logic [`cWishboneWidth-1 : 0] Data,
logic [`cWishboneWidth-1 : 0] TGA = '{default: cDontCare},
logic [`cWishboneWidth-1 : 0] TGD = cDontCare,
logic [`cWishboneWidth-1 : 0] BankSelect = '{default: 1});
 
@(posedge this.Bus.CLK_I)
// CLOCK EDGE 0
this.Bus.cbMaster.ADR_O <= Address;
this.Bus.cbMaster.TGA_O <= TGA;
this.Bus.cbMaster.DAT_O <= Data;
this.Bus.cbMaster.TGD_O <= TGD;
this.Bus.cbMaster.WE_O <= cAsserted;
this.Bus.cbMaster.SEL_O <= BankSelect;
this.Bus.cbMaster.CYC_O <= cAsserted;
this.Bus.cbMaster.TGC_O <= cAsserted; // Assert all?
this.Bus.cbMaster.STB_O <= cAsserted;
this.Bus.cbMaster.CTI_O <= ClassicCycle;
//$display("%t : MasterWrite: Waiting for slave response.", $time);
// Wait until slave responds
 
wait ((this.Bus.cbMaster.ACK_I == cAsserted)
|| (this.Bus.cbMaster.ERR_I == cAsserted)
|| (this.Bus.cbMaster.RTY_I == cAsserted));
checkResponse();
this.Bus.cbMaster.STB_O <= cNegated;
this.Bus.cbMaster.CYC_O <= cNegated;
 
@(posedge this.Bus.CLK_I);
// CLOCK EDGE 1
//$display("%t : MasterWrite completed.", $time);
endtask;
 
task BlockWrite (logic [`cWishboneWidth-1 : 0] Address,
logic [`cWishboneWidth-1 : 0] Data [],
logic [`cWishboneWidth-1 : 0] TGA = '{default: cDontCare},
logic [`cWishboneWidth-1 : 0] TGD = cDontCare,
logic [`cWishboneWidth-1 : 0] BankSelect = '{default: 1}
);
 
foreach(Data[i]) begin
 
@(posedge this.Bus.CLK_I)
// CLOCK EDGE 0
this.Bus.cbMaster.ADR_O <= Address + i;
this.Bus.cbMaster.TGA_O <= TGA;
this.Bus.cbMaster.DAT_O <= Data[i];
this.Bus.cbMaster.TGD_O <= TGD;
this.Bus.cbMaster.WE_O <= cAsserted;
this.Bus.cbMaster.SEL_O <= BankSelect;
this.Bus.cbMaster.CYC_O <= cAsserted;
this.Bus.cbMaster.TGC_O <= cAsserted; // Assert all?
this.Bus.cbMaster.STB_O <= cAsserted;
this.Bus.cbMaster.LOCK_O <= cAsserted;
this.Bus.cbMaster.CTI_O <= ClassicCycle;
 
// Wait until slave responds
wait ((this.Bus.cbMaster.ACK_I == cAsserted)
|| (this.Bus.cbMaster.ERR_I == cAsserted)
|| (this.Bus.cbMaster.RTY_I == cAsserted));
checkResponse();
//$display("%t : MasterBlockWrite phase %d completed.", $time, i);
end
 
this.Bus.cbMaster.STB_O <= cNegated;
this.Bus.cbMaster.CYC_O <= cNegated;
this.Bus.cbMaster.LOCK_O <= cNegated;
@(posedge this.Bus.CLK_I);
// CLOCK EDGE 1
//$display("%t : MasterBlockWrite completed.", $time);
endtask;
 
task TestSingleOps (logic [`cWishboneWidth-1 : 0] Address,
logic [`cWishboneWidth-1 : 0] Data);
 
logic [`cWishboneWidth-1 : 0] rd;
 
this.Write(Address, Data);
this.Read(Address, rd);
 
$display("%t : %h (read) == %h (written)", $time, rd, Data);
assert (rd == Data);
endtask;
 
task TestBlockOps (logic [`cWishboneWidth-1 : 0] Address,
logic [`cWishboneWidth-1 : 0] Data []);
 
logic [`cWishboneWidth-1 : 0] blockData [];
 
blockData = new [Data.size()];
 
this.BlockWrite(Address, Data);
this.BlockRead(Address, blockData);
 
foreach(blockData[i]) begin
$display("%t : %h (read) == %h (written)", $time, blockData[i], Data[i]);
assert (Data[i] == blockData[i]);
end
 
blockData.delete();
 
endtask;
 
endclass
 
/sdhc-sc-core/trunk/src/grpSd/unitSdWbSlave/src/tbSdWbSlave.sv
0,0 → 1,64
 
`define cWishboneWidth 32
const integer cWishboneWidth = 32;
const logic cAsserted = 1;
const logic cNegated = 0;
const logic cDontCare = 'X;
 
typedef logic [2:0] aCTI;
const aCTI ClassicCycle = "000";
 
include "../src/WishboneInterface.sv";
include "../src/Wishbone-BFM.sv";
 
 
program Test(WishboneInterface BusInterface);
initial begin
logic [31:0] data[];
Wishbone Bus = new(BusInterface.Master);
 
data = new [3];
data[0] = 'h01234567;
data[1] = 'h89ABCDEF;
data[2] = 'hFEDCBA98;
BusInterface.RST_I <= 1;
repeat (2) @BusInterface.cbMaster;
BusInterface.RST_I <= 0;
 
Bus.TestSingleOps('b001, 'h0000FFFF);
Bus.TestBlockOps('b000, data);
 
$display("%t : Test completed.", $time);
repeat(2) @(posedge BusInterface.CLK_I);
$finish;
end
endprogram
 
module Testbed();
WishboneInterface Bus();
always #10 Bus.CLK_I <= ~Bus.CLK_I;
 
SdWbSlaveWrapper Slave(
Bus.CLK_I,
Bus.RST_I,
Bus.CYC_O,
Bus.LOCK_O,
Bus.STB_O,
Bus.WE_O,
Bus.CTI_O,
Bus.BTE_O,
Bus.ACK_I,
Bus.ERR_I,
Bus.RTY_I,
Bus.SEL_O,
Bus.ADR_O,
Bus.DAT_O,
Bus.DAT_I,
'0,
'h00000000
);
 
Test Program(Bus);
endmodule
/sdhc-sc-core/trunk/src/grpSd/unitSdWbSlaveWrapper/src/SdWbSlaveWrapper-Rtl-ea.vhdl
0,0 → 1,91
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone.all;
use work.sdwb.all;
 
entity SdWbSlaveWrapper is
port (
iClk : in std_ulogic; -- Clock, rising clock edge
iRstSync : in std_ulogic; -- Reset, active high, synchronous
 
iCyc : in std_ulogic;
iLock : in std_ulogic;
iStb : in std_ulogic;
iWe : in std_ulogic;
iCti : in std_ulogic_vector(2 downto 0);
iBte : in std_ulogic_vector(1 downto 0);
oAck : out std_ulogic;
oErr : out std_ulogic;
oRty : out std_ulogic;
iSel : in std_ulogic_vector(0 downto 0);
iAdr : in std_ulogic_vector(6 downto 4);
iDat : in std_ulogic_vector(31 downto 0);
oDat : out std_ulogic_vector(31 downto 0);
iReqOperationEdge : in std_ulogic;
iReadData : in std_ulogic_vector(31 downto 0);
 
oAckOperationToggle : out std_ulogic;
oStartAddr : out std_ulogic_vector(31 downto 0);
oEndAddr : out std_ulogic_vector(31 downto 0);
oOperation : out std_ulogic_vector(31 downto 0);
oWriteData : out std_ulogic_vector(31 downto 0)
);
 
end entity SdWbSlaveWrapper;
 
architecture Rtl of SdWbSlaveWrapper is
 
signal iWbCtrl : aWbSlaveCtrlInput;
signal oWbCtrl : aWbSlaveCtrlOutput;
signal iWbDat : aSdWbSlaveDataInput;
signal oWbDat : aSdWbSlaveDataOutput;
signal oController : aSdWbSlaveToSdController;
signal iController : aSdControllerToSdWbSlave;
 
begin
iWbCtrl <= (
Cyc => iCyc,
Lock => iLock,
Stb => iStb,
We => iWe,
Cti => iCti,
Bte => iBte
);
 
oAck <= oWbCtrl.Ack;
oErr <= oWbCtrl.Err;
oRty <= oWbCtrl.Rty;
oDat <= oWbDat.Dat;
 
iWbDat <= (
Sel => iSel,
Adr => iAdr,
Dat => iDat
);
 
oAckOperationToggle <= oController.AckOperationToggle;
oOperation <= oController.OperationBlock.Operation;
oStartAddr <= oController.OperationBlock.StartAddr;
oEndAddr <= oController.OperationBlock.EndAddr;
oWriteData <= oController.WriteData;
 
iController <= (
ReqOperationEdge => iReqOperationEdge,
ReadData => iReadData
);
 
 
SdWbSlave_inst: entity work.SdWbSlave
port map (
iClk => iClk,
iRstSync => iRstSync,
iWbCtrl => iWbCtrl,
oWbCtrl => oWbCtrl,
iWbDat => iWbDat,
oWbDat => oWbDat ,
iController => iController,
oController => oController
);
 
end architecture Rtl;
/sdhc-sc-core/trunk/src/sim/sim.tcl
60,6 → 60,17
}
}
 
if [info exists svtb] {
foreach {grp unit} $svtb {
set fname ../../../grp$grp/unit$unit/src/tb$unit.sv
if [file isfile $fname] {
vlog $fname
} else {
echo "Svunit $grp $unit not found! ($fname)"
}
}
}
 
if [info exists svunits] {
foreach {grp unit} $svunits {
set fname ../../../grp$grp/unit$unit/src/$unit.sv

powered by: WebSVN 2.1.0

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