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