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 |