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

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.communication/] [n2h2/] [1.0/] [vhd/] [n2h2_rx_chan.vhd] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- Title      : N2H2 rx channel
3
-- Project    : 
4
-------------------------------------------------------------------------------
5
-- File       : n2h2_rx_chan.vhd
6
-- Author     : kulmala3
7
-- Created    : 02.06.2005
8
-- Last update: 2011-04-06
9
-- Description: One channel for N2H2
10
-- supports 32 and 64b data widths only due to low cost implemementation :)
11
-------------------------------------------------------------------------------
12
-- Copyright (c) 2005 
13
-------------------------------------------------------------------------------
14
-- Revisions  :
15
-- Date        Version  Author  Description
16
-- 02.06.2005  1.0      AK      Created
17
-------------------------------------------------------------------------------
18
 
19
library ieee;
20
use ieee.std_logic_1164.all;
21
use ieee.std_logic_arith.all;
22
use ieee.std_logic_unsigned.all;
23
 
24
entity n2h2_rx_chan is
25
 
26
  generic (
27
    data_width_g      : integer := 0;
28
    hibi_addr_width_g : integer := 0;
29
    addr_width_g      : integer := 0;
30
    amount_width_g    : integer := 0;
31
    addr_cmp_lo_g     : integer := 0;
32
    addr_cmp_hi_g     : integer := 0
33
    );
34
 
35
  port (
36
    clk   : in std_logic;
37
    rst_n : in std_logic;
38
 
39
    -- keep still until a new init
40
    avalon_addr_in : in std_logic_vector(addr_width_g-1 downto 0);
41
    hibi_addr_in   : in std_logic_vector(hibi_addr_width_g-1 downto 0);
42
    irq_amount_in  : in std_logic_vector(amount_width_g-1 downto 0);
43
 
44
    hibi_data_in      : in std_logic_vector(hibi_addr_width_g-1 downto 0);
45
    hibi_av_in        : in std_logic;
46
    hibi_empty_in     : in std_logic;
47
    init_in           : in std_logic;
48
    irq_ack_in        : in std_logic;
49
    avalon_waitreq_in : in std_logic;
50
    avalon_we_in      : in std_logic;
51
 
52
    avalon_addr_out    : out std_logic_vector(addr_width_g-1 downto 0);
53
    avalon_we_out      : out std_logic;
54
    avalon_be_out      : out std_logic_vector(data_width_g/8-1 downto 0);
55
    addr_match_out     : out std_logic;
56
    addr_match_cmb_out : out std_logic;
57
    irq_out            : out std_logic
58
    );
59
 
60
end n2h2_rx_chan;
61
 
62
architecture rtl of n2h2_rx_chan is
63
  constant dont_care_c   : std_logic := 'X';
64
  constant addr_offset_c : integer   := data_width_g/8;
65
 
66
  constant words_per_hibi_data_c : integer   := data_width_g/32;
67
  constant upper_valid_c         : std_logic := '0';  -- in case of odd data amount, is
68
-- either uppoer ('1') or lower ('0') half-word valid?
69
  constant be_width_c            : integer   := data_width_g/8;
70
  signal   addr_match_r          : std_logic;
71
  signal   addr_match_cmb_s      : std_logic;
72
  signal   avalon_addr_r         : std_logic_vector(addr_width_g-1 downto 0);
73
  signal   enable_r              : std_logic;
74
  signal   ena_av_empty          : std_logic_vector(2 downto 0);
75
  signal   irq_counter_r         : std_logic_vector(amount_width_g-1 downto 0);
76
  signal   irq_r                 : std_logic;
77
  signal   we_match_waitreq      : std_logic_vector(2 downto 0);
78
 
79
 
80
begin  -- rtl
81
 
82
  we_match_waitreq <= avalon_we_in & addr_match_r & avalon_waitreq_in;
83
  avalon_we_out    <= addr_match_r and enable_r;
84
  irq_out          <= irq_r;
85
 
86
  addr_match_out     <= addr_match_r and enable_r;
87
  addr_match_cmb_out <= addr_match_cmb_s;
88
  avalon_addr_out    <= avalon_addr_r;
89
 
90
  ena_av_empty <= enable_r & hibi_av_in & hibi_empty_in;
91
 
92
  addr_match : process (hibi_data_in, hibi_addr_in, addr_match_r, ena_av_empty)
93
  begin  -- process addr_match
94
 
95
    case ena_av_empty is
96
      when "000" | "010" | "011" | "001" =>
97
        addr_match_cmb_s <= '0';
98
      when "110" =>
99
        if hibi_data_in(addr_cmp_hi_g downto addr_cmp_lo_g) =
100
            hibi_addr_in(addr_cmp_hi_g downto addr_cmp_lo_g) then
101
            addr_match_cmb_s <= '1';
102
          else
103
            addr_match_cmb_s <= '0';
104
          end if;
105
      when others =>
106
        addr_match_cmb_s <= addr_match_r;
107
    end case;
108
 
109
  end process addr_match;
110
 
111
  addr_match_reg : process (clk, rst_n)
112
  begin  -- process addr_matching
113
    if rst_n = '0' then                 -- asynchronous reset (active low)
114
      addr_match_r <= '0';
115
    elsif clk'event and clk = '1' then  -- rising clock edge
116
 
117
      addr_match_r <= addr_match_cmb_s;
118
 
119
    end if;
120
  end process addr_match_reg;
121
 
122
 
123
  ena : process (clk, rst_n)
124
    variable inter_addr : std_logic_vector(addr_width_g-1 downto 0);
125
  begin  -- process ena
126
    if rst_n = '0' then                 -- asynchronous reset (active low)
127
      enable_r      <= '0';
128
      irq_counter_r <= (others => '1');
129
      avalon_addr_r <= (others => dont_care_c);
130
      irq_r         <= '0';
131
 
132
    elsif clk'event and clk = '1' then  -- rising clock edge
133
 
134
      if init_in = '1' then
135
        enable_r      <= '1';
136
        irq_counter_r <= irq_amount_in;
137
        avalon_addr_r <= avalon_addr_in;
138
      else
139
        enable_r      <= enable_r;
140
        irq_counter_r <= irq_counter_r;
141
        avalon_addr_r <= avalon_addr_r;
142
      end if;
143
 
144
      if irq_ack_in = '1' then
145
        irq_r <= '0';
146
      else
147
        irq_r <= irq_r;
148
      end if;
149
 
150
      case we_match_waitreq is
151
        when "110" =>
152
          -- we're writing here
153
          if irq_counter_r <= conv_std_logic_vector(words_per_hibi_data_c, amount_width_g) then
154
            avalon_addr_r <= avalon_addr_r+addr_offset_c;  -- what if not increased?
155
            enable_r      <= '0';
156
            irq_r         <= '1';
157
            irq_counter_r <= irq_counter_r;
158
          else
159
            avalon_addr_r <= avalon_addr_r +addr_offset_c;
160
            irq_counter_r <= irq_counter_r-words_per_hibi_data_c;
161
            enable_r      <= '1';
162
--            irq_r <= '0'; --already assigned earlier
163
          end if;
164
 
165
        when others =>
166
--          irq_counter_r <= irq_counter_r;
167
--          enable_r      <= enable_r;
168
--            irq_r <= '0';          
169
      end case;
170
 
171
      -- purpose: sets the avalon byteenable signal
172
 
173
 
174
    end if;
175
  end process ena;
176
 
177
  byteena : process (irq_counter_r)
178
  begin  -- process byteena
179
    if irq_counter_r = conv_std_logic_vector(1, amount_width_g) and words_per_hibi_data_c = 2 then
180
      -- odd number of words wanted, e.g. 64 bit hibi, wanted 5 32-bit
181
      -- words
182
      avalon_be_out(be_width_c-1 downto be_width_c/2) <= (others => upper_valid_c);
183
      avalon_be_out(be_width_c/2-1 downto 0)          <= (others => (not upper_valid_c));
184
    else
185
      avalon_be_out <= (others => '1');
186
    end if;
187
 
188
  end process byteena;
189
 
190
 
191
 
192
end rtl;

powered by: WebSVN 2.1.0

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