1 | library IEEE;
|
2 | use IEEE.STD_LOGIC_1164.ALL;
|
3 | use ieee.numeric_std.all;
|
4 | Library UNISIM;
|
5 | use UNISIM.vcomponents.all;
|
6 |
|
7 | entity HyperBus is Port(
|
8 | clk100: in std_logic;
|
9 | start: in std_logic;
|
10 | mem_regs: in std_logic; --0: Mem, 1: Regs
|
11 | burstlength: in std_logic; --0: 2Bytes, 1:64Bytes
|
12 | adr: in std_logic_vector(21 downto 0); -- 21 ... 9: 8192 Rows, 8 ... 0: 512 Words in 1 Row. (2 ... 0: 8 Words = 1 Half Page)
|
13 | snd_rcv: in std_logic; --0: send/write, 1: receive/read
|
14 | ready: out std_logic;
|
15 | --- SND ---
|
16 | data_snd: in std_logic_vector(64*8-1 downto 0);
|
17 | --- RCV --
|
18 | data_rcv_valid: out std_logic;
|
19 | data_rcv: out std_logic_vector(64*8-1 downto 0);
|
20 | --- RAM ---
|
21 | nReset: out std_logic;
|
22 | nCS: out std_logic;
|
23 | CK: out std_logic;
|
24 | nCK: out std_logic;
|
25 | PSC: out std_logic;
|
26 | nPSC: out std_logic;
|
27 | RWDS: inout std_logic;
|
28 | DQ: inout std_logic_vector(7 downto 0));
|
29 | end HyperBus;
|
30 |
|
31 | architecture Behavioral of HyperBus is
|
32 |
|
33 | component HyperBus_IN generic(
|
34 | SYS_W: integer := 8;
|
35 | DEV_W: integer := 16);
|
36 | port(
|
37 | data_in_from_pins : in std_logic_vector(SYS_W-1 downto 0);
|
38 | data_in_to_device : out std_logic_vector(DEV_W-1 downto 0);
|
39 | clk_in : in std_logic;
|
40 | clk_out : out std_logic;
|
41 | io_reset : in std_logic);
|
42 | end component;
|
43 |
|
44 | component HyperBus_Out generic(
|
45 | SYS_W: integer := 8;
|
46 | DEV_W: integer := 16);
|
47 | port(
|
48 | data_out_from_device : in std_logic_vector(DEV_W-1 downto 0);
|
49 | data_out_to_pins : out std_logic_vector(SYS_W-1 downto 0);
|
50 | clk_in : in std_logic;
|
51 | io_reset : in std_logic);
|
52 | end component;
|
53 |
|
54 | component HyperBus_Clocks port(
|
55 | clk_out_100 : out std_logic;
|
56 | clk_out_100_CK : out std_logic;
|
57 | clk_out_100_PSC : out std_logic;
|
58 | clk_in_100 : in std_logic);
|
59 | end component;
|
60 |
|
61 | signal MMCM_SYS: std_logic:='0';
|
62 | signal MMCM_CK: std_logic:='0';
|
63 | signal MMCM_PSC: std_logic:='0';
|
64 | signal CK_enable: std_logic:='0';
|
65 | signal Address_Space: std_logic:='0'; --0: Memory, 1: Registers
|
66 | signal Burst_Type: std_logic:='1'; --0: wrapped, 1: linear
|
67 | signal Burst_snd_rcv: std_logic:='0'; --0: send/write, 1: receive/read
|
68 | signal Burst_length: std_logic:='0'; --0: 2Bytes, 1:64Bytes
|
69 | signal Burst_counter_100: unsigned(7 downto 0):=(others => '1');
|
70 | signal RX_Data_Counter: integer range 0 to 127:=0;
|
71 | signal RX_Data: std_logic_vector(15 downto 0):=(others => '0');
|
72 | signal TX_Data: std_logic_vector(15 downto 0):=(others => '0');
|
73 | signal DQ_OUT: std_logic_vector(7 downto 0):=(others => '0');
|
74 | signal DQ_IN: std_logic_vector(7 downto 0):=(others => '0');
|
75 | signal DQ_tristate: std_logic:='0';
|
76 | signal RWDS_CLK: std_logic:='0';
|
77 | signal RWDS_OUT: std_logic:='0';
|
78 | signal RWDS_IN: std_logic:='0';
|
79 | signal RWDS_SET: std_logic:='0';
|
80 | signal RWDS_tristate: std_logic:='1';
|
81 | constant Resetcounter_max : integer := 2**16-1;
|
82 | signal Resetcounter: integer range 0 to Resetcounter_max:=0;
|
83 | signal end_Burst: integer range 0 to 255:=13;
|
84 | type Reg_Array is array (0 to 91) of std_logic_vector(7 downto 0);
|
85 | signal Reg: Reg_Array :=(others => x"00");
|
86 | type Rcv_Array is array (0 to 63) of std_logic_vector(7 downto 0);
|
87 | signal Rcv: Rcv_Array :=(others => x"00");
|
88 |
|
89 | begin
|
90 |
|
91 | HB_IN: HyperBus_IN port map(
|
92 | data_in_from_pins => DQ_IN,
|
93 | data_in_to_device => RX_Data,
|
94 | clk_in => RWDS_IN,
|
95 | clk_out => RWDS_CLK,
|
96 | io_reset => '0');
|
97 |
|
98 | HB_Out: HyperBus_Out port map(
|
99 | data_out_from_device => TX_Data,
|
100 | data_out_to_pins => DQ_OUT,
|
101 | clk_in => MMCM_SYS,
|
102 | io_reset => '0');
|
103 |
|
104 | MMCM_HyperBus : HyperBus_Clocks port map(
|
105 | clk_out_100 => MMCM_SYS,
|
106 | clk_out_100_CK => MMCM_CK,
|
107 | clk_out_100_PSC => MMCM_PSC,
|
108 | clk_in_100 => clk100);
|
109 |
|
110 | DQ <= DQ_OUT when DQ_tristate = '0' else "ZZZZZZZZ";
|
111 | DQ_IN <= DQ;
|
112 |
|
113 |
|
114 | RWDS <= RWDS_OUT when RWDS_tristate = '0' else 'Z';
|
115 | RWDS_IN <= RWDS;
|
116 |
|
117 | process begin
|
118 | wait until rising_edge(MMCM_SYS);
|
119 | nReset <= '1';
|
120 | data_rcv_valid <= '0';
|
121 | if Resetcounter < Resetcounter_max then
|
122 | --nCS <= '1';
|
123 | Resetcounter <= Resetcounter +1;
|
124 | if Resetcounter > Resetcounter_max -400 and Resetcounter < Resetcounter_max -300 then
|
125 | nReset <= '0';
|
126 | end if;
|
127 |
|
128 | else
|
129 | if Burst_counter_100 < end_Burst+4 then
|
130 | Burst_counter_100 <= Burst_counter_100 +1;
|
131 | if Burst_counter_100 > 0 and Burst_counter_100 < 3 and RWDS_IN = '1' then
|
132 | RWDS_SET <= '1';
|
133 | end if;
|
134 | if Burst_counter_100 = 0 then
|
135 | CK_enable <= '1';
|
136 | end if;
|
137 | if Burst_counter_100 = 3 then
|
138 | if RWDS_SET = '0' then
|
139 | Burst_counter_100 <= Burst_counter_100 +7;
|
140 | end if;
|
141 | end if;
|
142 | if Burst_counter_100 = 13 then
|
143 | if Burst_snd_rcv = '0' then
|
144 | RWDS_tristate <= '0';
|
145 | end if;
|
146 | end if;
|
147 | if Burst_counter_100 = end_Burst then
|
148 | TX_Data <= x"0000";
|
149 | end if;
|
150 | if Burst_counter_100 < end_Burst then
|
151 | TX_Data <= Reg(2*to_integer(Burst_counter_100)+3) & Reg(2*to_integer(Burst_counter_100)+2);
|
152 | end if;
|
153 | if Burst_counter_100 = end_Burst+1 then
|
154 | CK_enable <= '0';
|
155 | end if;
|
156 | if Burst_counter_100 = end_Burst+2 then
|
157 | RWDS_tristate <= '0';
|
158 | if Burst_snd_rcv = '1' then
|
159 | if Burst_length = '0' then
|
160 | data_rcv(15 downto 0) <= RX_Data(15 downto 0);
|
161 | data_rcv(511 downto 16) <= (others => '0');
|
162 | else
|
163 | for I in 0 to 61 loop
|
164 | data_rcv(I*8+7 downto I*8) <= Rcv(I);
|
165 | end loop;
|
166 | data_rcv(511 downto 496) <= RX_Data(15 downto 0);
|
167 | end if;
|
168 | data_rcv_valid <= '1';
|
169 | end if;
|
170 | end if;
|
171 | else
|
172 | if start = '1' then
|
173 | RWDS_SET <= '0';
|
174 | RWDS_tristate <= '1';
|
175 | Burst_counter_100 <= (others => '0');
|
176 | Burst_length <= burstlength;
|
177 | Burst_snd_rcv <= snd_rcv;
|
178 | Address_Space <= mem_regs;
|
179 | if burstlength = '0' then
|
180 | end_Burst <= 2+6+6+1-1;
|
181 | else
|
182 | end_Burst <= 2+6+6+32-1;
|
183 | end if;
|
184 | Reg(0) <= snd_rcv & mem_regs & Burst_Type & "00000";
|
185 | Reg(1) <= "00000" & adr(21 downto 19);
|
186 | Reg(2) <= adr(18 downto 11);
|
187 | Reg(3) <= adr(10 downto 3);
|
188 | Reg(4) <= "00000000";
|
189 | Reg(5) <= "00000" & adr(2 downto 0);
|
190 | for I in 0 to 63 loop
|
191 | if snd_rcv = '0' then
|
192 | Reg(I+28) <= data_snd(I*8+7 downto I*8);
|
193 | else
|
194 | Reg(I+28) <= x"00";
|
195 | end if;
|
196 | end loop;
|
197 | TX_Data <= "00000" & adr(21 downto 19) & snd_rcv & mem_regs & Burst_Type & "00000";
|
198 | end if;
|
199 | end if;
|
200 | end if;
|
201 | end process;
|
202 |
|
203 | process (Burst_counter_100,RWDS_CLK,end_Burst,start)
|
204 | begin
|
205 | if start = '1' then
|
206 | RX_Data_Counter <= 0;
|
207 | elsif rising_edge(RWDS_CLK) then
|
208 | if Burst_counter_100 < end_Burst+2 and Burst_counter_100 > 13 and Burst_snd_rcv = '1' then
|
209 | RX_Data_Counter <= RX_Data_Counter +1;
|
210 | if RX_Data_Counter > 0 then
|
211 | Rcv((RX_Data_Counter-1)*2+1) <= RX_Data(15 downto 8);
|
212 | Rcv((RX_Data_Counter-1)*2) <= RX_Data(7 downto 0);
|
213 | end if;
|
214 | end if;
|
215 | end if;
|
216 | end process;
|
217 |
|
218 | nCS <= '0' when (start = '1' or Burst_counter_100 < end_Burst+3) and Resetcounter = Resetcounter_max else '1';
|
219 |
|
220 | ready <= '1' when start = '0' and Burst_counter_100 > end_Burst+3 else '0';
|
221 |
|
222 | DQ_tristate <= '0' when Burst_counter_100 < 5 or Burst_snd_rcv = '0' else '1';
|
223 |
|
224 | --PSC <= MMCM_PSC when Burst_counter_100 > 13 and Burst_counter_100 < end_Burst+2 and Burst_snd_rcv = '1' else '0';
|
225 | --nPSC <= not MMCM_PSC when Burst_counter_100 > 13 and Burst_counter_100 < end_Burst+2 and Burst_snd_rcv = '1' else '1';
|
226 |
|
227 | PSC <= 'Z';
|
228 | nPSC <= 'Z';
|
229 |
|
230 | CK <= MMCM_CK when CK_enable = '1' else '0';
|
231 | nCK <= not MMCM_CK when CK_enable = '1' else '1';
|
232 |
|
233 | end Behavioral;
|