1 |
3 |
axuan25268 |
-------------------------------------------------------------------------------
|
2 |
|
|
-- Title :
|
3 |
|
|
-- Project :
|
4 |
|
|
-------------------------------------------------------------------------------
|
5 |
|
|
-- File : rgmii_tx_buf.vhd
|
6 |
|
|
-- Author : liyi <alxiuyain@foxmail.com>
|
7 |
|
|
-- Company : OE@HUST
|
8 |
|
|
-- Created : 2013-05-06
|
9 |
|
|
-- Last update: 2013-05-20
|
10 |
|
|
-- Platform :
|
11 |
|
|
-- Standard : VHDL'93/02
|
12 |
|
|
-------------------------------------------------------------------------------
|
13 |
|
|
-- Description:
|
14 |
|
|
-------------------------------------------------------------------------------
|
15 |
|
|
-- Copyright (c) 2013 OE@HUST
|
16 |
|
|
-------------------------------------------------------------------------------
|
17 |
|
|
-- Revisions :
|
18 |
|
|
-- Date Version Author Description
|
19 |
|
|
-- 2013-05-06 1.0 liyi Created
|
20 |
|
|
-------------------------------------------------------------------------------
|
21 |
|
|
LIBRARY ieee;
|
22 |
|
|
USE ieee.std_logic_1164.ALL;
|
23 |
|
|
USE ieee.numeric_std.ALL;
|
24 |
|
|
-------------------------------------------------------------------------------
|
25 |
|
|
ENTITY rgmii_tx_buf IS
|
26 |
|
|
|
27 |
|
|
PORT (
|
28 |
|
|
iEthClk : IN STD_LOGIC;
|
29 |
|
|
iWbClk : IN STD_LOGIC;
|
30 |
|
|
iRst_n : IN STD_LOGIC;
|
31 |
|
|
|
32 |
|
|
--oEthTxLen : OUT UNSIGNED(15 DOWNTO 0);
|
33 |
|
|
oEthTxData : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
|
34 |
|
|
iEthSOF : IN STD_LOGIC;
|
35 |
|
|
oEthEOF : OUT STD_LOGIC;
|
36 |
|
|
oEthGenFrame : OUT STD_LOGIC;
|
37 |
|
|
iEthGenFrameAck : IN STD_LOGIC;
|
38 |
|
|
|
39 |
|
|
iWbTxData : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
|
40 |
|
|
iWbTxAddr : IN UNSIGNED(10 DOWNTO 0);
|
41 |
|
|
iWbTxDataWr : IN STD_LOGIC;
|
42 |
|
|
iWbTxInfo : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
|
43 |
|
|
iWbTxInfoWr : IN STD_LOGIC;
|
44 |
|
|
|
45 |
|
|
iWbIntEn : IN STD_LOGIC;
|
46 |
|
|
iWbIntClr : IN STD_LOGIC;
|
47 |
|
|
oWbInt : OUT STD_LOGIC;
|
48 |
|
|
oWbTxInfo : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
|
49 |
|
|
);
|
50 |
|
|
|
51 |
|
|
END ENTITY rgmii_tx_buf;
|
52 |
|
|
-------------------------------------------------------------------------------
|
53 |
|
|
ARCHITECTURE rtl OF rgmii_tx_buf IS
|
54 |
|
|
|
55 |
|
|
CONSTANT DATA_WIDTH : NATURAL := 32;
|
56 |
|
|
CONSTANT ADDR_WIDTH : NATURAL := 11;
|
57 |
|
|
-- Build a 2-D array type for the RAM
|
58 |
|
|
SUBTYPE word_t IS STD_LOGIC_VECTOR((DATA_WIDTH-1) DOWNTO 0);
|
59 |
|
|
TYPE memory_t IS ARRAY(2**ADDR_WIDTH-1 DOWNTO 0) OF word_t;
|
60 |
|
|
-- Declare the RAM signal.
|
61 |
|
|
SIGNAL ram : memory_t;
|
62 |
|
|
SIGNAL raddr : UNSIGNED(ADDR_WIDTH-1 DOWNTO 0) := (OTHERS => '0');
|
63 |
|
|
--SIGNAL waddr : UNSIGNED(ADDR_WIDTH-1 DOWNTO 0) := (OTHERS => '0');
|
64 |
|
|
SIGNAL rWE : STD_LOGIC := '0';
|
65 |
|
|
SIGNAL rTxData : STD_LOGIC_VECTOR(31 DOWNTO 0);
|
66 |
|
|
|
67 |
|
|
SIGNAL cInfoFifoEmpty : STD_LOGIC;
|
68 |
|
|
SIGNAL cInfoFifoFull : STD_LOGIC;
|
69 |
|
|
SIGNAL cInfo : STD_LOGIC_VECTOR(31 DOWNTO 0);
|
70 |
|
|
BEGIN -- ARCHITECTURE rtl
|
71 |
|
|
|
72 |
|
|
blk2 : BLOCK IS
|
73 |
|
|
SIGNAL rWbTxInfo : STD_LOGIC_VECTOR(31 DOWNTO 0);
|
74 |
|
|
BEGIN -- BLOCK blk2
|
75 |
|
|
oWbTxInfo(1 DOWNTO 0) <= B"00";
|
76 |
|
|
oWbTxInfo(31) <= cInfoFifoFull;
|
77 |
|
|
oWbTxInfo(30 DOWNTO ADDR_WIDTH+16) <= (OTHERS => '0');
|
78 |
|
|
-- tell the tx wbm module the next frame begin address in the buffer
|
79 |
|
|
-- this infomation will be send back to this module!
|
80 |
|
|
-- oWbTxInfo(ADDR_WIDTH+15 DOWNTO 16) <= STD_LOGIC_VECTOR(waddr);
|
81 |
|
|
oWbTxInfo(ADDR_WIDTH+15 DOWNTO 16) <= STD_LOGIC_VECTOR(iWbTxAddr);
|
82 |
|
|
PROCESS (iWbClk, iRst_n) IS
|
83 |
|
|
BEGIN
|
84 |
|
|
IF iRst_n = '0' THEN
|
85 |
|
|
rWbTxInfo(15 DOWNTO 2) <= (OTHERS => '0');
|
86 |
|
|
oWbTxInfo(15 DOWNTO 2) <= (OTHERS => '0');
|
87 |
|
|
ELSIF rising_edge(iWbClk) THEN
|
88 |
|
|
rWbTxInfo(15 DOWNTO 2) <= STD_LOGIC_VECTOR(
|
89 |
|
|
TO_UNSIGNED(
|
90 |
|
|
--2**ADDR_WIDTH - TO_INTEGER(waddr) + TO_INTEGER(raddr), 14));
|
91 |
|
|
2**ADDR_WIDTH - TO_INTEGER(iWbTxAddr) + TO_INTEGER(raddr), 14));
|
92 |
|
|
oWbTxInfo(15 DOWNTO 2) <= rWbTxInfo(15 DOWNTO 2);
|
93 |
|
|
END IF;
|
94 |
|
|
END PROCESS;
|
95 |
|
|
END BLOCK blk2;
|
96 |
|
|
|
97 |
|
|
--PROCESS (iWbClk, iRst_n) IS
|
98 |
|
|
--BEGIN
|
99 |
|
|
-- IF iRst_n = '0' THEN
|
100 |
|
|
-- waddr <= (OTHERS => '0');
|
101 |
|
|
-- ELSIF rising_edge(iWbClk) THEN
|
102 |
|
|
-- IF iWbTxDataWr = '1' THEN
|
103 |
|
|
-- waddr <= waddr + 1;
|
104 |
|
|
-- END IF;
|
105 |
|
|
-- END IF;
|
106 |
|
|
--END PROCESS;
|
107 |
|
|
|
108 |
|
|
blk1 : BLOCK IS
|
109 |
|
|
--SIGNAL rWordCnt : UNSIGNED(15 DOWNTO 2);
|
110 |
|
|
SIGNAL rByteCnt : UNSIGNED(15 DOWNTO 0);
|
111 |
|
|
SIGNAL rLen : UNSIGNED(15 DOWNTO 0);
|
112 |
|
|
--SIGNAL rRipple : UNSIGNED(1 DOWNTO 0);
|
113 |
|
|
SIGNAL rFinished : STD_LOGIC;
|
114 |
|
|
TYPE state_t IS (IDLE, WAIT1, DATA);
|
115 |
|
|
SIGNAL rState : state_t;
|
116 |
|
|
BEGIN -- BLOCK blk1
|
117 |
|
|
PROCESS (iEthClk, iRst_n) IS
|
118 |
|
|
BEGIN
|
119 |
|
|
IF iRst_n = '0' THEN
|
120 |
|
|
raddr <= (OTHERS => '0');
|
121 |
|
|
--rWordCnt <= (OTHERS => '0');
|
122 |
|
|
--rRipple <= (OTHERS => '0');
|
123 |
|
|
rState <= IDLE;
|
124 |
|
|
oEthGenFrame <= '0';
|
125 |
|
|
oEthTxData <= (OTHERS => '0');
|
126 |
|
|
oWbInt <= '0';
|
127 |
|
|
oEthEOF <= '0';
|
128 |
|
|
rByteCnt <= (OTHERS => '0');
|
129 |
|
|
rFinished <= '0';
|
130 |
|
|
ELSIF rising_edge(iEthClk) THEN
|
131 |
|
|
oEthEOF <= '0';
|
132 |
|
|
IF iWbIntClr = '1' THEN
|
133 |
|
|
oWbInt <= '0';
|
134 |
|
|
END IF;
|
135 |
|
|
CASE rState IS
|
136 |
|
|
WHEN IDLE =>
|
137 |
|
|
rFinished <= '0';
|
138 |
|
|
rByteCnt <= (OTHERS => '0');
|
139 |
|
|
IF cInfoFifoEmpty = '0' THEN
|
140 |
|
|
oEthGenFrame <= '1';
|
141 |
|
|
END IF;
|
142 |
|
|
IF iEthGenFrameAck = '1' THEN
|
143 |
|
|
oEthGenFrame <= '0';
|
144 |
|
|
rState <= WAIT1;
|
145 |
|
|
END IF;
|
146 |
|
|
---------------------------------------------------------------------
|
147 |
|
|
WHEN WAIT1 =>
|
148 |
|
|
--IF cInfo(1 DOWNTO 0) /= B"00" THEN
|
149 |
|
|
-- rWordCnt <= UNSIGNED(cInfo(15 DOWNTO 2));
|
150 |
|
|
--ELSE
|
151 |
|
|
-- rWordCnt <= UNSIGNED(cInfo(15 DOWNTO 2)) - 1;
|
152 |
|
|
--END IF;
|
153 |
|
|
rLen <= UNSIGNED(cInfo(15 DOWNTO 0)) - 1;
|
154 |
|
|
raddr <= UNSIGNED(cInfo(ADDR_WIDTH+15 DOWNTO 16));
|
155 |
|
|
-- there's same clock cycles before iEthSOF asserted....
|
156 |
|
|
IF iEthSOF = '1' THEN
|
157 |
|
|
rState <= DATA;
|
158 |
|
|
END IF;
|
159 |
|
|
---------------------------------------------------------------------
|
160 |
|
|
WHEN DATA =>
|
161 |
|
|
--rRipple <= rRipple + 1;
|
162 |
|
|
rByteCnt <= rByteCnt + 1;
|
163 |
|
|
--CASE rRipple IS
|
164 |
|
|
IF rByteCnt = rLen THEN
|
165 |
|
|
oEthEOF <= '1';
|
166 |
|
|
rFinished <= '1';
|
167 |
|
|
END IF;
|
168 |
|
|
CASE rByteCnt(1 DOWNTO 0) IS
|
169 |
|
|
WHEN B"00" => oEthTxData <= rTxData(31 DOWNTO 24);
|
170 |
|
|
WHEN B"01" => oEthTxData <= rTxData(23 DOWNTO 16);
|
171 |
|
|
WHEN B"10" =>
|
172 |
|
|
oEthTxData <= rTxData(15 DOWNTO 8);
|
173 |
|
|
raddr <= raddr + 1;
|
174 |
|
|
WHEN B"11" =>
|
175 |
|
|
oEthTxData <= rTxData(7 DOWNTO 0);
|
176 |
|
|
--rWordCnt <= rWordCnt - 1;
|
177 |
|
|
--IF rWordCnt = X"000"&B"00" THEN
|
178 |
|
|
IF rFinished = '1' OR rByteCnt = rLen THEN
|
179 |
|
|
rState <= IDLE;
|
180 |
|
|
oWbInt <= iWbIntEn;
|
181 |
|
|
END IF;
|
182 |
|
|
WHEN OTHERS => NULL;
|
183 |
|
|
END CASE;
|
184 |
|
|
---------------------------------------------------------------------
|
185 |
|
|
WHEN OTHERS => NULL;
|
186 |
|
|
END CASE;
|
187 |
|
|
END IF;
|
188 |
|
|
END PROCESS;
|
189 |
|
|
END BLOCK blk1;
|
190 |
|
|
|
191 |
|
|
-----------------------------------------------------------------------------
|
192 |
|
|
-- data buffer
|
193 |
|
|
-----------------------------------------------------------------------------
|
194 |
|
|
PROCESS(iWbClk)
|
195 |
|
|
BEGIN
|
196 |
|
|
IF(rising_edge(iWbClk)) THEN
|
197 |
|
|
IF(iWbTxDataWr = '1') THEN
|
198 |
|
|
--ram(TO_INTEGER(waddr)) <= iWbTxData;
|
199 |
|
|
ram(TO_INTEGER(iWbTxAddr)) <= iWbTxData;
|
200 |
|
|
END IF;
|
201 |
|
|
END IF;
|
202 |
|
|
END PROCESS;
|
203 |
|
|
PROCESS(iEthClk)
|
204 |
|
|
BEGIN
|
205 |
|
|
IF(rising_edge(iEthClk)) THEN
|
206 |
|
|
rTxData <= ram(TO_INTEGER(raddr));
|
207 |
|
|
END IF;
|
208 |
|
|
END PROCESS;
|
209 |
|
|
|
210 |
|
|
--oEthTxLen <= UNSIGNED(cInfo(15 DOWNTO 0));
|
211 |
|
|
fifo32x8_1 : ENTITY work.fifo32x8
|
212 |
|
|
PORT MAP (
|
213 |
|
|
data => iWbTxInfo,
|
214 |
|
|
rdclk => iEthClk,
|
215 |
|
|
rdreq => iEthGenFrameAck,
|
216 |
|
|
wrclk => iWbClk,
|
217 |
|
|
wrreq => iWbTxInfoWr,
|
218 |
|
|
q => cInfo,
|
219 |
|
|
rdempty => cInfoFifoEmpty,
|
220 |
|
|
wrfull => cInfoFifoFull);
|
221 |
|
|
|
222 |
|
|
END ARCHITECTURE rtl;
|