📄 mii.tdf
字号:
%-----------------------------------------------------------------------%
% Description : %
% Edit history... %
% Date Engineer Rev Changes %
% 3 Oct, 97 SBJ 000 Initial stab %
% %
% This module can be used to read or write management registers %
% implemented on an MII interface. As currently implemented, only %
% runs through the command sequence once upon negation of /Rst and %
% only uses "constants" for the parameters. It should be relatively %
% easy to modify to accept parameters as "run-time" inputs. %
% %
%-----------------------------------------------------------------------%
TITLE "MII Management control through MDC/MDIO port.";
PARAMETERS
%---------------------------------------------------------------------------
OPCODE "READ" or "WRITE". Selects whether to read or write
register contents.
ADDRESS 0-31. Select PHY to access.
REGISTER 0-31. Select management register to access.
CMD h"0"-h"FFFF". Command data value (only applicable for
writes).
DIVIDE_BY >0. Clock frequency divided by 2^this number to create
MDC frequency.
---------------------------------------------------------------------------%
(
OPCODE = "WRITE", -- Note, default values are only for test.
ADDRESS = 1,
REGISTER = 19,
CMD = h"0400",
DIVIDE_BY = 1
);
CONSTANT CDIV_ROLL_OVER = (2 ^ ( DIVIDE_BY ) ) - 1;
SUBDESIGN mii
%---------------------------------------------------------------------------
Clk System clock input.
/Rst Low active asynchronous reset input.
MDC Management data clock output.
port. This could be switched to a normal output.
MDIO Management data input/output. This is a tristate driver.
It could also be changed to an open-collector output
if a sufficiently strong pull-up resistor is used.
Data[] Data (or command).
Done Signal asserted after sequence complete.
---------------------------------------------------------------------------%
(
Clk : INPUT; --
/Rst : INPUT; --
MDC : OUTPUT;--
MDIO : BIDIR; --
Data[15..0] : OUTPUT;--
Done : OUTPUT;--
)
VARIABLE
%---------------------------------------------------------------------------
moe MDIO tri-state buffer control.
cntr[] Sequence counter that counts out 64-bit sequence.
bit_stream[] 64-bit preamble/sfd/opcode/address/register/etc stream.
cdiv[] Clock divisor counter used to divide down input clock
frequency to MDC clock frequency. MDC frequency should
be no faster than 2.5MHz.
next_bit When asserted, allows cntr[] to advance.
---------------------------------------------------------------------------%
MDIO : TRI;
Done : DFF;
Data[15..0] : DFFE;
moe : DFF;
cntr[5..0] : DFFE; -- 64-bit sequence counter
bit_stream[0..63] : NODE; -- 64-bit stream
cdiv[DIVIDE_BY-1..0] : DFF; -- Clock divisor counter
next_bit : NODE;
BEGIN
%---------------------------------------------------------------------------
Outputs
---------------------------------------------------------------------------%
--
-- Use msb of clock divider as MDC output.
--
MDC = cdiv[DIVIDE_BY-1];
--
-- Funnel 64-bit bit-stream through MDIO output, lsb first.
--
FOR bit IN 0 TO 63 GENERATE
MDIO.in = ( cntr[] == bit ) & bit_stream[bit];
END GENERATE;
MDIO.oe = moe;
--
-- Signal that sequence done after 64-bit sequence. (NOTE: Sequence is only
-- generated once upon negation of /Rst).
--
Done.( clk, clrn )= ( Clk, /Rst );
Done = ( cntr[] == 63 ) & next_bit;
--
-- Capture data portion of sequence. For writes, of course, this is
-- redundant to CMD parameter. Data bit 15 is captured during bit_stream
-- sequence bit 48 to data bit 0 at bit_stream sequence bit 63.
--
Data[].( clk ) = ( Clk );
FOR bit IN 0 TO 15 GENERATE
Data[bit].ena = ( cntr[] == ( 63 - bit ) ) & next_bit;
END GENERATE;
Data[] = MDIO;
%---------------------------------------------------------------------------
Check input parameters
---------------------------------------------------------------------------%
ASSERT (OPCODE == "READ" OR OPCODE == "WRITE")
REPORT "Value of OPCODE parameter (%) must be ""READ"" or ""WRITE""."
OPCODE
SEVERITY ERROR;
ASSERT (ADDRESS >= 0 AND ADDRESS < 32)
REPORT "Value of ADDRESS parameter (%) must be be >= 0 and < 32."
ADDRESS
SEVERITY ERROR;
ASSERT (REGISTER >= 0 AND REGISTER < 32)
REPORT "Value of REGISTER parameter (%) must be be >= 0 and < 32."
REGISTER
SEVERITY ERROR;
ASSERT (CMD > 0 AND CMD < 65536)
REPORT "Value of CMD parameter (%) must be be > 0 and <= 0xFFFF."
CMD
SEVERITY ERROR;
ASSERT (DIVIDE_BY > 0)
REPORT "Value of DIVIDE_BY parameter (%) must be be > 0."
CMD
SEVERITY ERROR;
%---------------------------------------------------------------------------
Generate logic for 64-bit MDIO stream. Read and write frame structures
are basically similar except for opcode and data. Since MDIO will be
tri-stated (from our end) during reads, data is a don't care for reads.
---------------------------------------------------------------------------%
bit_stream[0..31] = VCC; -- Preamble, all 1's
bit_stream[32..33] = b"01"; -- SOF
IF OPCODE == "READ" GENERATE -- Opcode
bit_stream[34..35]= b"10";
ELSE GENERATE
bit_stream[34..35]= b"01";
END GENERATE;
bit_stream[36..40] = ADDRESS; -- Address
bit_stream[41..45] = REGISTER; -- Register
bit_stream[46..47] = b"10"; -- TA (turn around)
bit_stream[48..63] = CMD; -- Data
%---------------------------------------------------------------------------
Divide down input clock frequency by 16 to MDC clock frequency (must be
<= 2.5MHz). Note that cdiv[] msb is used as MDC output.
---------------------------------------------------------------------------%
cdiv[].( clk, clrn ) = ( Clk, /Rst );
IF ( DIVIDE_BY > 1 ) GENERATE
cdiv[] = cdiv[] + 1;
ELSE GENERATE
cdiv[] = !cdiv[];
END GENERATE;
next_bit = cdiv[] == CDIV_ROLL_OVER;
%---------------------------------------------------------------------------
64-bit bit-stream sequence counter. Increment every time cdiv[] is about
to roll-over.
---------------------------------------------------------------------------%
cntr[].( clk, clrn ) = ( Clk, /Rst );
cntr[].ena = next_bit;
cntr[] = cntr[] + 1;
%---------------------------------------------------------------------------
Control MDIO tri-state driver. Only enabled during 64-bit sequence (writes)
or for first 46-bits (reads).
---------------------------------------------------------------------------%
moe.( clk, prn ) = ( Clk, /Rst );
IF OPCODE == "READ" GENERATE
moe = moe & !( ( cntr[] == 46 ) & next_bit );
ELSE GENERATE
moe = moe & !( ( cntr[] == 63 ) & next_bit );
END GENERATE;
END;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -