]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - hw/irc_proc_main.vhd
Merge 8x IRC support from origin/master branch into bluebot branch.
[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         generic map (num_irc_g)
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         -- FIXME: Template needs to support 1-bit WE enabling, getting KEEP conflicts on wea here
63         ram: xilinx_dualport_bram_no_change
64         generic map
65         (
66                 we_width      => 4,
67                 byte_width    => 8,
68                 address_width => ram_addr_s'length
69         )
70         port map
71         (
72                 -- Internal
73                 clka  => clk_i,
74                 rsta  => reset_i,
75                 ena   => ram_en_s,
76                 wea   => ram_write_s,
77                 addra => ram_addr_s,
78                 dina  => ram_data_i_s,
79                 douta => ram_data_o_s,
80                 -- External
81                 clkb  => mem_clk_i,
82                 rstb  => '0',
83                 enb   => mem_en_i,
84                 web   => mem_we_i,
85                 addrb => mem_addr_i,
86                 dinb  => mem_data_i,
87                 doutb => mem_data_o
88         );
89
90         -- RAM address
91         ram_addr_s     <= axis_s & op_s(1);
92
93 update:
94         process (irc_i, op_r, axis_r, ram_data_o_s, reset_i)
95                 variable skip_v            : std_logic;
96                 variable irc_v             : IRC_COUNT_OUTPUT_Type;
97                 variable res_v             : std_logic_vector(31 downto 0);
98                 variable count_v           : std_logic_vector(31 downto 0);
99         begin
100
101                 -- Init (reset the index reset events)
102                 irc_index_reset_o <= (others => '0');
103                 ram_en_s          <= '0';
104                 ram_write_s       <= "0000";
105                 ram_data_i_s      <= (others => '0');
106
107                 count_v     := (others => '0');
108                 skip_v      := '1';
109
110                 -- No reset
111                 if reset_i = '0' then
112
113                         -- Caluclating step
114                         if op_r(1) = '0' then
115                                 -- get source
116                                 irc_v := irc_i(to_integer(unsigned(axis_r)));
117
118                                 if op_r(0) = '0' then
119                                         count_v(7 downto 0) := irc_v.qcount;
120                                         skip_v := '0';
121                                 else
122                                         if irc_v.index_event = '1' then
123                                                 irc_index_reset_o(to_integer(unsigned(axis_r))) <= '1';
124                                                 count_v(7 downto 0) := irc_v.index;
125                                                 skip_v := '0';
126                                         end if;
127                                 end if;
128
129                                 if skip_v = '0' then
130                                         -- signed extension
131                                         if count_v(7) = '1' then
132                                                 count_v(31 downto 8) := (others => '1');
133                                         else
134                                                 count_v(31 downto 8) := (others => '0');
135                                         end if;
136
137                                         -- calculate qs8
138                                         ep_add32nc(count_v, not ram_data_o_s, '1', res_v);
139
140                                         -- extend it
141                                         count_v(7 downto 0) := res_v(7 downto 0);
142
143                                         if res_v(7) = '1' then
144                                                 count_v(31 downto 8) := (others => '1');
145                                         else
146                                                 count_v(31 downto 8) := (others => '0');
147                                         end if;
148
149                                         -- add it back
150                                         ep_add32nc(ram_data_o_s, count_v, '0', res_v);
151
152                                         -- store it
153                                         ram_en_s     <= '1';
154                                         ram_write_s  <= "1111";
155                                         ram_data_i_s <= res_v;
156                                 end if;
157
158                         end if;
159
160                         -- Read next stored IRC
161                         if op_r = "11" then
162                                 ram_en_s <= '1';
163                         end if;
164
165                 end if;
166         end process;
167
168 seq:
169         process
170         begin
171
172                 wait until clk_i'event and clk_i = '1';
173                 op_r     <= op_s;
174                 axis_r   <= axis_s;
175
176         end process;
177
178 end Behavioral;