]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - hw/irc_proc_main.vhd
IRC coprocesor, change to generic, index to user, usb commands update
[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.util_pkg.all;
7 use work.lx_rocon_pkg.all;
8
9 -- Main unit in the IRC cooprocessor
10 -- This could be written as generic (n IRC axes)
11 -- >100 MHz
12 entity irc_proc_main is
13         generic
14         (
15                 num_irc_g  : positive := 4
16         );
17         port
18         (
19                 -- Basic input
20                 clk_i             : in std_logic;
21                 reset_i           : in std_logic;
22                 -- Signals from IRC
23                 irc_i             : in IRC_COUNT_OUTPUT_Array_Type((num_irc_g-1) downto 0);
24                 -- Index resetting
25                 irc_index_reset_o : out std_logic_vector((num_irc_g-1) downto 0);
26                 -- BRAM access
27                 mem_clk_i         : in std_logic;
28     mem_en_i          : in std_logic;
29     mem_we_i          : in std_logic_vector(3 downto 0);
30     mem_addr_i        : in std_logic_vector(ceil_log2(num_irc_g) downto 0);
31     mem_data_i        : in std_logic_vector(31 downto 0);
32     mem_data_o        : out std_logic_vector(31 downto 0)
33         );
34 end irc_proc_main;
35
36 architecture Behavioral of irc_proc_main is
37
38         signal op_s         : std_logic_vector(1 downto 0);
39         signal axis_s       : std_logic_vector((ceil_log2(num_irc_g)-1) downto 0);
40         --
41         signal op_r         : std_logic_vector(1 downto 0);
42         signal axis_r       : std_logic_vector((ceil_log2(num_irc_g)-1) downto 0);
43         --
44         signal ram_en_s     : std_logic;
45         signal ram_addr_s   : std_logic_vector((mem_addr_i'length-1) downto 0);
46         signal ram_write_s  : std_logic_vector(3 downto 0);
47         signal ram_data_i_s : std_logic_vector(31 downto 0);
48         signal ram_data_o_s : std_logic_vector(31 downto 0);
49
50 begin
51
52         incr: irc_proc_inc
53         port map
54         (
55                 clk_i   => clk_i,
56                 reset_i => reset_i,
57                 op_o    => op_s,
58                 axis_o  => axis_s
59         );
60
61         -- FIXME: Template needs to support 1-bit WE enabling, getting KEEP conflicts on wea here
62         ram: xilinx_dualport_bram_no_change
63         generic map
64         (
65                 we_width      => 4,
66                 byte_width    => 8,
67                 address_width => ram_addr_s'length
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
90         ram_addr_s     <= axis_s & op_s(1);
91
92 update:
93         process (irc_i, op_r, axis_r, ram_data_o_s, reset_i)
94                 variable skip_v            : std_logic;
95                 variable irc_v             : IRC_COUNT_OUTPUT_Type;
96                 variable res_v             : std_logic_vector(31 downto 0);
97                 variable count_v           : std_logic_vector(31 downto 0);
98         begin
99
100                 -- Init (reset the index reset events)
101                 irc_index_reset_o <= (others => '0');
102                 ram_en_s          <= '0';
103                 ram_write_s       <= "0000";
104                 ram_data_i_s      <= (others => '0');
105
106                 count_v     := (others => '0');
107                 skip_v      := '1';
108
109                 -- No reset
110                 if reset_i = '0' then
111
112                         -- Caluclating step
113                         if op_r(1) = '0' then
114                                 -- get source
115                                 irc_v := irc_i(to_integer(unsigned(axis_r)));
116
117                                 if op_r(0) = '0' then
118                                         count_v(7 downto 0) := irc_v.qcount;
119                                         skip_v := '0';
120                                 else
121                                         if irc_v.index_event = '1' then
122                                                 irc_index_reset_o(to_integer(unsigned(axis_r))) <= '1';
123                                                 count_v(7 downto 0) := irc_v.index;
124                                                 skip_v := '0';
125                                         end if;
126                                 end if;
127
128                                 if skip_v = '0' then
129                                         -- signed extension
130                                         if count_v(7) = '1' then
131                                                 count_v(31 downto 8) := (others => '1');
132                                         else
133                                                 count_v(31 downto 8) := (others => '0');
134                                         end if;
135
136                                         -- calculate qs8
137                                         ep_add32nc(count_v, not ram_data_o_s, '1', res_v);
138
139                                         -- extend it
140                                         count_v(7 downto 0) := res_v(7 downto 0);
141
142                                         if res_v(7) = '1' then
143                                                 count_v(31 downto 8) := (others => '1');
144                                         else
145                                                 count_v(31 downto 8) := (others => '0');
146                                         end if;
147
148                                         -- add it back
149                                         ep_add32nc(ram_data_o_s, count_v, '0', res_v);
150
151                                         -- store it
152                                         ram_en_s     <= '1';
153                                         ram_write_s  <= "1111";
154                                         ram_data_i_s <= res_v;
155                                 end if;
156
157                         end if;
158
159                         -- Read next stored IRC
160                         if op_r = "11" then
161                                 ram_en_s <= '1';
162                         end if;
163
164                 end if;
165         end process;
166
167 seq:
168         process
169         begin
170
171                 wait until clk_i'event and clk_i = '1';
172                 op_r     <= op_s;
173                 axis_r   <= axis_s;
174
175         end process;
176
177 end Behavioral;