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