OpenCores
URL https://opencores.org/ocsvn/funbase_ip_library/funbase_ip_library/trunk

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [Altera/] [ip.hwp.cpu/] [nios_ii_sram/] [1.0/] [hdl/] [ip/] [hpd_rx_stream.vhd] - Blame information for rev 147

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 147 lanttu
-------------------------------------------------------------------------------
2
-- Title      : HIBI PE DMA - streaming rx channel
3
-- Project    : 
4
-------------------------------------------------------------------------------
5
-- File       : hpd_rx_stream.vhd
6
-- Author     : Lasse Lehtonen
7
-- Created    : 2012-01-10
8
-- Last update: 2012-02-28
9
-------------------------------------------------------------------------------
10
-- Copyright (c) 2012
11
-------------------------------------------------------------------------------
12
-- Revisions  :
13
-- Date        Version  Author  Description
14
-- 2012-01-10  1.0      LL      Created
15
-------------------------------------------------------------------------------
16
 
17
library ieee;
18
use ieee.std_logic_1164.all;
19
use ieee.std_logic_arith.all;
20
use ieee.std_logic_unsigned.all;
21
 
22
entity hpd_rx_stream is
23
 
24
  generic (
25
    data_width_g      : integer := 0;
26
    hibi_addr_width_g : integer := 0;
27
    addr_width_g      : integer := 0;
28
    words_width_g     : integer := 0;
29
    addr_cmp_lo_g     : integer := 0;
30
    addr_cmp_hi_g     : integer := 0
31
    );
32
 
33
  port (
34
    clk   : in std_logic;
35
    rst_n : in std_logic;
36
 
37
    -- keep still until a new init
38
    avalon_addr_in : in std_logic_vector(addr_width_g-1 downto 0);
39
    hibi_addr_in   : in std_logic_vector(hibi_addr_width_g-1 downto 0);
40
    irq_words_in   : in std_logic_vector(words_width_g-1 downto 0);
41
 
42
    hibi_data_in      : in std_logic_vector(hibi_addr_width_g-1 downto 0);
43
    hibi_av_in        : in std_logic;
44
    hibi_empty_in     : in std_logic;
45
    init_in           : in std_logic;
46
    irq_ack_in        : in std_logic;
47
    avalon_waitreq_in : in std_logic;
48
    avalon_we_in      : in std_logic;
49
 
50
    avalon_addr_out    : out std_logic_vector(addr_width_g-1 downto 0);
51
    avalon_we_out      : out std_logic;
52
    avalon_be_out      : out std_logic_vector(data_width_g/8-1 downto 0);
53
    addr_match_out     : out std_logic;
54
    addr_match_cmb_out : out std_logic;
55
    irq_out            : out std_logic;
56
    -- new words in buffer
57
    words_out          : out std_logic_vector(words_width_g-1 downto 0);
58
    read_ack_in        : in  std_logic
59
    );
60
 
61
end hpd_rx_stream;
62
 
63
architecture rtl of hpd_rx_stream is
64
 
65
  constant addr_offset_c : integer := data_width_g/8;
66
 
67
  constant words_per_hibi_data_c : integer   := data_width_g/32;
68
  constant upper_valid_c         : std_logic := '0';
69
  -- in case of odd data words, is
70
  -- either upper ('1') or lower ('0') half-word valid?
71
 
72
  constant be_width_c       : integer := data_width_g/8;
73
  signal   addr_match_r     : std_logic;
74
  signal   addr_match_cmb_s : std_logic;
75
  signal   write_addr_r     : std_logic_vector(addr_width_g-1 downto 0);
76
  signal   enable_r         : std_logic;
77
  signal   ena_av_empty     : std_logic_vector(2 downto 0);
78
  signal   read_counter_r   : std_logic_vector(words_width_g-1 downto 0);
79
  signal   irq_counter_r    : std_logic_vector(words_width_g-1 downto 0);
80
  signal   cnt_max_r        : std_logic_vector(words_width_g-1 downto 0);
81
  signal   irq_r            : std_logic;
82
  signal   we_match_waitreq : std_logic_vector(2 downto 0);
83
  signal   ena_reading_r    : std_logic;
84
  signal   words_out_r      : std_logic_vector(words_width_g-1 downto 0);
85
  signal   hibi_av_in_r     : std_logic;
86
 
87
begin  -- rtl
88
 
89
  we_match_waitreq <= avalon_we_in & addr_match_r & avalon_waitreq_in;
90
  avalon_we_out    <= addr_match_r and enable_r and ena_reading_r;
91
  irq_out          <= irq_r;
92
 
93
  addr_match_out     <= addr_match_r and enable_r;
94
  addr_match_cmb_out <= addr_match_cmb_s;
95
  avalon_addr_out    <= write_addr_r;
96
 
97
  ena_av_empty <= enable_r & hibi_av_in & hibi_empty_in;
98
 
99
  words_out <= words_out_r;
100
 
101
  addr_match : process (hibi_data_in, hibi_addr_in, addr_match_r, ena_av_empty)
102
  begin  -- process addr_match
103
 
104
    case ena_av_empty is
105
      when "000" | "010" | "011" | "001" =>
106
        addr_match_cmb_s <= '0';
107
      when "110" =>
108
        if hibi_data_in(addr_cmp_hi_g downto addr_cmp_lo_g) =
109
          hibi_addr_in(addr_cmp_hi_g downto addr_cmp_lo_g) then
110
          addr_match_cmb_s <= '1';
111
        else
112
          addr_match_cmb_s <= '0';
113
        end if;
114
      when others =>
115
        addr_match_cmb_s <= addr_match_r;
116
    end case;
117
 
118
  end process addr_match;
119
 
120
  addr_match_reg : process (clk, rst_n)
121
  begin  -- process addr_matching
122
    if rst_n = '0' then                 -- asynchronous reset (active low)
123
      addr_match_r <= '0';
124
    elsif clk'event and clk = '1' then  -- rising clock edge
125
      addr_match_r <= addr_match_cmb_s;
126
    end if;
127
  end process addr_match_reg;
128
 
129
 
130
  ena : process (clk, rst_n)
131
    variable inter_addr     : std_logic_vector(addr_width_g-1 downto 0);
132
    variable read_counter_v : std_logic_vector(words_width_g-1 downto 0);
133
  begin  -- process ena
134
    if rst_n = '0' then                 -- asynchronous reset (active low)
135
      enable_r       <= '0';
136
      irq_counter_r  <= (others => '0');
137
      read_counter_r <= (others => '0');
138
      write_addr_r   <= (others => '0');
139
      cnt_max_r      <= (others => '0');
140
      irq_r          <= '0';
141
      ena_reading_r  <= '0';
142
      words_out_r    <= (others => '0');
143
      hibi_av_in_r   <= '0';
144
    elsif clk'event and clk = '1' then  -- rising clock edge
145
 
146
      words_out_r <= read_counter_r - irq_counter_r;
147
 
148
      read_counter_v := read_counter_r;
149
 
150
      hibi_av_in_r <= hibi_av_in;
151
 
152
      if init_in = '1' then
153
        enable_r       <= '1';
154
        ena_reading_r  <= '1';
155
        read_counter_r <= irq_words_in;
156
        irq_counter_r  <= irq_words_in;
157
        cnt_max_r      <= irq_words_in;
158
        write_addr_r   <= avalon_addr_in;
159
      end if;
160
 
161
      if read_ack_in = '1' then
162
        read_counter_v := read_counter_r - irq_words_in;
163
        read_counter_r <= read_counter_v;
164
        if read_counter_v = 0 then
165
          read_counter_r <= cnt_max_r;
166
          irq_counter_r  <= cnt_max_r;
167
          write_addr_r   <= avalon_addr_in;
168
        end if;
169
        if enable_r = '0' then          -- 
170
          read_counter_r <= irq_words_in;
171
          irq_counter_r  <= irq_words_in;
172
          cnt_max_r      <= irq_words_in;
173
        end if;
174
        ena_reading_r <= '1';
175
      end if;
176
 
177
      if irq_ack_in = '1' then
178
        irq_r <= '0';
179
      else
180
        irq_r <= irq_r;
181
      end if;
182
 
183
      if ena_reading_r = '1' then
184
 
185
        case we_match_waitreq is
186
          when "110" =>
187
            -- we're writing here
188
            if irq_counter_r <= conv_std_logic_vector(words_per_hibi_data_c,
189
                                                      words_width_g)
190
            then
191
              write_addr_r  <= write_addr_r + addr_offset_c;
192
              ena_reading_r <= '0';
193
              irq_r         <= '1';
194
              irq_counter_r <= irq_counter_r - words_per_hibi_data_c;
195
            else
196
              write_addr_r  <= write_addr_r + addr_offset_c;
197
              irq_counter_r <= irq_counter_r - words_per_hibi_data_c;
198
            end if;
199
 
200
          when others =>
201
            if irq_counter_r /= read_counter_r
202
              and (hibi_av_in = '0' or hibi_av_in_r = '1')
203
            then
204
              ena_reading_r <= '0';
205
              irq_r         <= '1';
206
            end if;
207
 
208
        end case;
209
 
210
      end if;
211
 
212
    end if;
213
  end process ena;
214
 
215
  byteena : process (irq_counter_r)
216
  begin  -- process byteena
217
    if irq_counter_r = conv_std_logic_vector(1, words_width_g)
218
      and words_per_hibi_data_c = 2
219
    then
220
      -- odd number of words wanted, e.g. 64 bit hibi, wanted 5 32-bit
221
      -- words
222
      avalon_be_out(be_width_c-1 downto be_width_c/2) <=
223
        (others => upper_valid_c);
224
      avalon_be_out(be_width_c/2-1 downto 0) <=
225
        (others => (not upper_valid_c));
226
    else
227
      avalon_be_out <= (others => '1');
228
    end if;
229
 
230
  end process byteena;
231
 
232
 
233
 
234
end rtl;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.