HyperBus.vhd


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;