]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - hw/irc_proc_main.vhd
ad4a7e801266368b5e53eb273ae002b6da025860
[fpga/lx-cpu1/lx-rocon.git] / hw / irc_proc_main.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.std_logic_unsigned.all;
4 use ieee.numeric_std.all;
5 use work.mbl_Pkg.all;
6 use work.lx_rocon_pkg.all;
7
8 -- Main unit in the IRC cooprocessor
9 entity irc_proc_main is
10         port
11         (
12                 -- Basic input
13                 clk_i             : in std_logic;
14                 reset_i           : in std_logic;
15                 -- Signals from IRC
16                 irc1_i            : in IRC_SLIM_OUTPUT_Type;
17                 irc2_i            : in IRC_SLIM_OUTPUT_Type;
18                 irc3_i            : in IRC_SLIM_OUTPUT_Type;
19                 irc4_i            : in IRC_SLIM_OUTPUT_Type;
20                 -- Index resetting
21                 irc_index_reset_o : out std_logic_vector(3 downto 0);
22                 -- BRAM access (the other port)
23                 mem_clk_i         : in std_logic;
24     mem_en_i          : in std_logic;
25     mem_we_i          : in std_logic_vector(3 downto 0);
26     mem_addr_i        : in std_logic_vector(2 downto 0);
27     mem_data_i        : in std_logic_vector(31 downto 0);
28     mem_data_o        : out std_logic_vector(31 downto 0)
29         );
30 end irc_proc_main;
31
32 architecture Behavioral of irc_proc_main is
33
34         -- IRC Output array
35         type IRC_OUTPUT_Array_Type is array (0 to 3) of IRC_SLIM_OUTPUT_Type;
36         --
37         signal op_s                : std_logic_vector(1 downto 0);
38         signal axis_s              : std_logic_vector(1 downto 0);
39         --
40         signal op_r                : std_logic_vector(1 downto 0);
41         signal axis_r              : std_logic_vector(1 downto 0);
42         --
43         signal irc_array_s         : IRC_OUTPUT_Array_Type;
44         --
45         signal ram_en_s            : std_logic;
46         signal ram_addr_s          : std_logic_vector(2 downto 0);
47         signal ram_write_s         : std_logic_vector(3 downto 0);
48         signal ram_data_i_s        : std_logic_vector(31 downto 0);
49         signal ram_data_o_s        : std_logic_vector(31 downto 0);
50
51 begin
52
53         incr: irc_proc_inc
54         port map
55         (
56                 clk_i   => clk_i,
57                 reset_i => reset_i,
58                 op_o    => op_s,
59                 axis_o  => axis_s
60         );
61
62         ram: xilinx_dualport_bram_no_change
63         generic map
64         (
65                 we_width      => 4,
66                 byte_width    => 8,
67                 address_width => 3
68         )
69         port map
70         (
71                 -- Internal
72                 clka  => clk_i,
73                 rsta  => reset_i,
74                 ena   => ram_en_s,
75                 wea   => ram_write_s,
76                 addra => ram_addr_s,
77                 dina  => ram_data_i_s,
78                 douta => ram_data_o_s,
79                 -- External
80                 clkb  => mem_clk_i,
81                 rstb  => '0',
82                 enb   => mem_en_i,
83                 web   => mem_we_i,
84                 addrb => mem_addr_i,
85                 dinb  => mem_data_i,
86                 doutb => mem_data_o
87         );
88
89         -- RAM address (delayed by a cycle when writing)
90         ram_addr_s     <= (axis_r & op_r(1)) when ram_write_s = "1111" else (axis_s & op_s(1));
91         -- IRC packing
92         irc_array_s(0) <= irc1_i;
93         irc_array_s(1) <= irc2_i;
94         irc_array_s(2) <= irc3_i;
95         irc_array_s(3) <= irc4_i;
96
97 seq:
98         process (clk_i)
99
100                 variable skip_v            : std_logic;
101                 variable irc_v             : IRC_SLIM_OUTPUT_Type;
102                 variable res_v             : std_logic_vector(31 downto 0);
103                 variable count_v           : std_logic_vector(31 downto 0);
104
105         begin
106
107                 if clk_i = '1' and clk_i'event then
108
109                         -- Init (reset the index reset events)
110                         irc_index_reset_o <= (others => '0');
111
112                         if reset_i = '1' then
113                                 -- Reset
114                                 ram_en_s     <= '1';
115                                 ram_write_s  <= "0000";
116                                 ram_data_i_s <= (others => '0');
117                                 --
118                                 op_r         <= (others => '0');
119                                 axis_r       <= (others => '0');
120
121                         else
122                                 -- Defaults
123                                 skip_v      := '1';
124                                 ram_en_s    <= '0';
125                                 ram_write_s <= "0000";
126
127                                 -- Caluclating step
128                                 if op_r(1) = '0' then
129                                         -- get source
130                                         irc_v := irc_array_s(to_integer(unsigned(axis_s)));
131
132                                         if op_r(0) = '0' then
133                                                 count_v(7 downto 0) := irc_v.qcount;
134                                                 skip_v := '0';
135                                         else
136                                                 if irc_v.index_event = '1' then
137                                                         irc_index_reset_o(to_integer(unsigned(axis_s))) <= '1';
138                                                         count_v(7 downto 0) := irc_v.index;
139                                                         skip_v := '0';
140                                                 end if;
141                                         end if;
142
143                                         if skip_v = '0' then
144                                                 -- signed extension
145                                                 if count_v(7) = '1' then
146                                                         count_v(31 downto 8) := (others => '1');
147                                                 else
148                                                         count_v(31 downto 8) := (others => '0');
149                                                 end if;
150
151                                                 -- calculate qs8
152                                                 ep_add32nc(count_v, not ram_data_o_s, '1', res_v);
153
154                                                 -- extend it
155                                                 count_v(7 downto 0) := res_v(7 downto 0);
156
157                                                 if res_v(7) = '1' then
158                                                         count_v(31 downto 8) := (others => '1');
159                                                 else
160                                                         count_v(31 downto 8) := (others => '0');
161                                                 end if;
162
163                                                 -- add it back
164                                                 ep_add32nc(ram_data_o_s, count_v, '0', res_v);
165
166                                                 -- store it
167                                                 ram_en_s     <= '1';
168                                                 ram_write_s  <= "1111";
169                                                 ram_data_i_s <= res_v;
170                                         end if;
171
172                                 end if;
173
174                                 -- Read next stored IRC
175                                 if op_r = "10" then
176                                         ram_en_s <= '1';
177                                 end if;
178
179                         end if;
180
181                         op_r     <= op_s;
182                         axis_r   <= axis_s;
183
184                 end if;
185
186         end process;
187
188 end Behavioral;