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/unitSdClockMaster
- from Rev 126 to Rev 129
- ↔ Reverse comparison
Rev 126 → Rev 129
/Files.tcl
0,0 → 1,5
set pkgs {Global Global} |
set units {Sd SdClockMaster Rtl} |
set psl(SdClockMaster) SdClockMaster |
set tb {Sd SdClockMaster Bhv} |
|
/src/tbSdClockMaster-Bhv-ea.vhdl
0,0 → 1,66
-- |
-- Title: Testbench for SD Clock Master |
-- File: tbSdClockMaster-Bhv-ea.vhdl |
-- Author: Copyright 2010: Rainer Kastl |
-- Standard: VHDL'93 |
-- |
-- Description: Simple, non automated testbench, because the design is very simple. |
-- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use work.global.all; |
|
entity tbSdClockMaster is |
end entity tbSdClockMaster; |
|
architecture Bhv of tbSdClockMaster is |
|
signal Clk : std_ulogic := cInactivated; |
constant cClkFrequency : natural := 100E6; |
constant cClkPeriod : time := (1 sec / cClkFrequency); |
signal RstSync : std_ulogic := cActivated; |
constant cResetTime : time := 5 * cClkPeriod; |
signal Finished : boolean := false; |
|
-- DUT signals |
|
signal iHighSpeed, iDisable : std_ulogic := cInactivated; |
signal oStrobe, oSdClk : std_ulogic; |
|
begin |
|
-- generate clock and reset |
|
Clk <= not Clk after cClkPeriod / 2 when Finished = false else cInactivated; |
RstSync <= cInactivated after cResetTime; |
|
-- stimuli |
|
stimuli : process |
begin |
iHighSpeed <= cActivated after 1000 ns, |
cInactivated after 1025 ns, |
cActivated after 1305 ns; |
|
iDisable <= cActivated after 2345 ns; |
Finished <= true after 5000 ns; |
wait; |
end process stimuli; |
|
DUT: entity work.SdClockMaster |
port map( |
iClk => Clk, |
iRstSync => RstSync, |
|
iHighSpeed => iHighSpeed, |
iDisable => iDisable, |
|
oSdStrobe => oStrobe, |
oSdCardClk => oSdClk |
); |
|
|
end architecture Bhv; |
|
/src/SdClockMaster-Rtl-a.vhdl
9,106 → 9,92
|
architecture Rtl of SdClockMaster is |
|
signal SdClk : std_ulogic; |
signal Counter : natural range 0 to 3; |
signal SdStrobe25MHz : std_ulogic; |
signal SdStrobe50MHz : std_ulogic; |
signal Disable : std_ulogic; |
subtype aCounter is unsigned(1 downto 0); -- maximal division through 4 |
|
type aRegSet is record |
Counter : aCounter; |
Clk : std_ulogic; |
Strobe : std_ulogic; |
HighSpeed : std_ulogic; |
end record aRegSet; |
|
signal R,NxR : aRegSet; |
|
begin |
|
SdClk100MHz: if gClkFrequency = 100E6 generate |
-- connect outputs with registers |
oSdCardClk <= R.Clk; |
oSdStrobe <= R.Strobe; |
|
ClkDivider : process (iClk, iRstSync) |
begin |
if (rising_edge(iClk)) then |
Regs : process (iClk, iRstSync) |
begin |
if (rising_edge(iClk)) then |
|
-- synchronous reset |
if (iRstSync = cActivated) then |
Counter <= 0; |
SdClk <= cInactivated; |
else |
if (iDisable = cActivated and SdClk = cInactivated) then |
Disable <= cActivated; |
else |
-- synchronous reset |
if (iRstSync = cActivated) then |
|
if (Disable = cActivated and iDisable = cInactivated) then |
Disable <= cInactivated; |
else |
R.Counter <= to_unsigned(0, R.Counter'length); |
R.Clk <= cInactivated; |
R.Strobe <= cInactivated; |
R.HighSpeed <= cInactivated; |
|
if (iHighSpeed = cActivated) then |
if (Counter = 0 or Counter = 2) then |
SdClk <= cActivated; |
else |
SdClk <= cInactivated; |
end if; |
else |
if (Counter = 0 or Counter = 1) then |
SdClk <= cActivated; |
else |
SdClk <= cInactivated; |
end if; |
end if; |
else |
R <= NxR; |
|
if (Counter < 3) then |
Counter <= Counter + 1; |
else |
Counter <= 0; |
end if; |
end if; |
end if; |
end if; |
end if; |
end process ClkDivider; |
end if; |
end process Regs; |
|
Comb : process (R, iHighSpeed, iDisable) |
begin |
|
RegSdStrobe : process (iClk, iRstSync) |
begin |
if (rising_edge(iClk)) then |
-- synchronous reset |
if (iRstSync = cActivated) then |
oSdCardClk <= cInactivated; |
oSdStrobe <= cInactivated; |
else |
-- defaults |
|
if (iDisable = cActivated) then |
oSdCardClk <= cInactivated; |
oSdStrobe <= cInactivated; |
NxR <= R; |
NxR.Counter <= R.Counter + 1; |
|
else |
-- generate clock and strobe |
case R.HighSpeed is |
when cInactivated => -- default mode |
NxR.Clk <= R.Counter(1); |
|
oSdCardClk <= not SdClk; |
case R.Counter is |
when "00" | "01" | "11" => |
NxR.Strobe <= cInactivated; |
|
if (iHighSpeed = cInactivated) then |
oSdStrobe <= SdStrobe25MHz; |
else |
oSdStrobe <= SdStrobe50MHz; |
end if; |
when "10" => |
NxR.Strobe <= cActivated; |
|
end if; |
when others => |
NxR.Strobe <= 'X'; |
end case; |
|
when cActivated => -- High-Speed mode |
NxR.Clk <= R.Counter(0); |
NxR.Strobe <= not R.Counter(0); |
|
when others => |
NxR.Clk <= 'X'; |
end case; |
|
-- switch speeds |
case R.HighSpeed is |
when cInactivated => |
if (R.Counter = 3) then |
NxR.HighSpeed <= iHighSpeed; |
end if; |
end if; |
end process RegSdStrobe; |
|
SdStrobe_inst25: entity work.StrobeGen(Rtl) |
generic map ( |
gClkFrequency => gClkFrequency, |
gStrobeCycleTime => 1 sec / 25E6) |
port map ( |
iClk => iClk, |
iRstSync => iRstSync, |
oStrobe => SdStrobe25MHz); |
when cActivated => |
if (R.Counter(0) = '1') then |
NxR.HighSpeed <= iHighSpeed; |
end if; |
|
SdStrobe_inst50: entity work.StrobeGen(Rtl) |
generic map ( |
gClkFrequency => gClkFrequency, |
gStrobeCycleTime => 1 sec / 50E6) |
port map ( |
iClk => iClk, |
iRstSync => iRstSync, |
oStrobe => SdStrobe50MHz); |
when others => |
NxR.HighSpeed <= 'X'; |
end case; |
|
end generate; |
end process Comb; |
|
|
end architecture Rtl; |
|
/src/SdClockMaster.psl
0,0 → 1,15
-- PSL assertions for SdClockMaster |
|
vunit vSdClockMaster(SdClockMaster) { |
default clock is (iClk'event and iClk='1'); |
|
-- strobe at least one clock cycle before falling edge |
assert always ({oSdStrobe} |=> {(not oSdStrobe) ; (not oSdStrobe and oSdCardClk)[*] ; not oSdCardClk}); |
|
-- check speed |
assert always ({iHighSpeed and oSdCardClk} |=> {not oSdCardClk; oSdCardClk}); |
|
-- check disable |
assert always ({iDisable} |=> not oSdCardClk and not oSdStrobe); |
} |
|
/src/SdClockMaster-e.vhdl
18,18 → 18,20
gClkFrequency : natural := 100E6 |
); |
port ( |
iClk : in std_ulogic; |
iRstSync : in std_ulogic; |
iHighSpeed : in std_ulogic; |
iDisable : in std_ulogic; |
oSdStrobe : out std_ulogic; |
oSdCardClk : out std_ulogic |
iClk : in std_ulogic; -- Clock active high |
iRstSync : in std_ulogic; -- Synchronous reset active high |
|
iHighSpeed : in std_ulogic; -- Switches between High-Speed (50 MHz) and default mode (25 MHz) |
iDisable : in std_ulogic; -- Disables the clock output |
|
oSdStrobe : out std_ulogic; -- strobe signal to enable SdCmd and SdData |
oSdCardClk : out std_ulogic -- clock output to SD card |
); |
|
begin |
|
assert (gClkFrequency = 100E6) |
report "SdCore needs an SdClk with 100 MHz" |
report "SdCore needs a SdClk with 100 MHz" |
severity failure; |
|
end entity SdClockMaster; |
/sim/SdClockMaster.tcl
0,0 → 1,2
source ../Files.tcl |
source ../../../sim/sim.tcl |
/sim/SdClockMaster-unattended.tcl
0,0 → 1,3
set script SdClockMaster.tcl |
|
do "../../../sim/unattended.tcl" |
/sim/Makefile
0,0 → 1,7
include ../../../../Makefile.rules |
|
all: SdClockMaster-unattended.sim |
|
clean: |
rm -rf vsim.wlf work |
|