]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - hw/irc_proc_main.vhd
Multiple patches
[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 -- This could be written as generic (n IRC axes)
10 -- >100 MHz
11 entity irc_proc_main is
12         port
13         (
14                 -- Basic input
15                 clk_i             : in std_logic;
16                 reset_i           : in std_logic;
17                 -- Signals from IRC
18                 irc_i             : in IRC_COUNT_OUTPUT_Array_Type(3 downto 0);
19                 -- Index resetting
20                 irc_index_reset_o : out std_logic_vector(3 downto 0);
21                 -- BRAM access
22                 mem_clk_i         : in std_logic;
23     mem_en_i          : in std_logic;
24     mem_we_i          : in std_logic_vector(3 downto 0);
25     mem_addr_i        : in std_logic_vector(2 downto 0);
26     mem_data_i        : in std_logic_vector(31 downto 0);
27     mem_data_o        : out std_logic_vector(31 downto 0)
28         );
29 end irc_proc_main;
30
31 architecture Behavioral of irc_proc_main is
32
33         signal op_s         : std_logic_vector(1 downto 0);
34         signal axis_s       : std_logic_vector(1 downto 0);
35         --
36         signal op_r         : std_logic_vector(1 downto 0);
37         signal axis_r       : std_logic_vector(1 downto 0);
38         --
39         signal ram_en_s     : std_logic;
40         signal ram_addr_s   : std_logic_vector(2 downto 0);
41         signal ram_write_s  : std_logic_vector(3 downto 0);
42         signal ram_data_i_s : std_logic_vector(31 downto 0);
43         signal ram_data_o_s : std_logic_vector(31 downto 0);
44
45 begin
46
47         incr: irc_proc_inc
48         port map
49         (
50                 clk_i   => clk_i,
51                 reset_i => reset_i,
52                 op_o    => op_s,
53                 axis_o  => axis_s
54         );
55
56         ram: xilinx_dualport_bram_no_change
57         generic map
58         (
59                 we_width      => 4,
60                 byte_width    => 8,
61                 address_width => 3
62         )
63         port map
64         (
65                 -- Internal
66                 clka  => clk_i,
67                 rsta  => reset_i,
68                 ena   => ram_en_s,
69                 wea   => ram_write_s,
70                 addra => ram_addr_s,
71                 dina  => ram_data_i_s,
72                 douta => ram_data_o_s,
73                 -- External
74                 clkb  => mem_clk_i,
75                 rstb  => '0',
76                 enb   => mem_en_i,
77                 web   => mem_we_i,
78                 addrb => mem_addr_i,
79                 dinb  => mem_data_i,
80                 doutb => mem_data_o
81         );
82
83         -- RAM address (delayed by a cycle when writing)
84         ram_addr_s     <= (axis_r & op_r(1)) when ram_write_s = "1111" else (axis_s & op_s(1));
85
86 seq:
87         process
88
89                 variable skip_v            : std_logic;
90                 variable irc_v             : IRC_COUNT_OUTPUT_Type;
91                 variable res_v             : std_logic_vector(31 downto 0);
92                 variable count_v           : std_logic_vector(31 downto 0);
93
94         begin
95
96                 wait until clk_i'event and clk_i = '1';
97
98                 -- Init (reset the index reset events)
99                 irc_index_reset_o <= (others => '0');
100
101                 if reset_i = '1' then
102                         -- Reset
103                         ram_en_s     <= '1';
104                         ram_write_s  <= "0000";
105                         ram_data_i_s <= (others => '0');
106                         --
107                         op_r         <= (others => '0');
108                         axis_r       <= (others => '0');
109
110                 else
111                         -- Defaults
112                         skip_v      := '1';
113                         ram_en_s    <= '0';
114                         ram_write_s <= "0000";
115
116                         -- Caluclating step
117                         if op_r(1) = '0' then
118                                 -- get source
119                                 irc_v := irc_i(to_integer(unsigned(axis_s)));
120
121                                 if op_r(0) = '0' then
122                                         count_v(7 downto 0) := irc_v.qcount;
123                                         skip_v := '0';
124                                 else
125                                         if irc_v.index_event = '1' then
126                                                 irc_index_reset_o(to_integer(unsigned(axis_s))) <= '1';
127                                                 count_v(7 downto 0) := irc_v.index;
128                                                 skip_v := '0';
129                                         end if;
130                                 end if;
131
132                                 if skip_v = '0' then
133                                         -- signed extension
134                                         if count_v(7) = '1' then
135                                                 count_v(31 downto 8) := (others => '1');
136                                         else
137                                                 count_v(31 downto 8) := (others => '0');
138                                         end if;
139
140                                         -- calculate qs8
141                                         ep_add32nc(count_v, not ram_data_o_s, '1', res_v);
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                                         ep_add32nc(ram_data_o_s, count_v, '0', res_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                         -- FIXME: Wire the enabling directly so it takes one cycle less,
165                         -- although op_r = "11" is reserved for potential extesion for 2nd index,
166                         -- so not very important
167                         if op_r = "10" then
168                                 ram_en_s <= '1';
169                         end if;
170
171                 end if;
172
173                 op_r     <= op_s;
174                 axis_r   <= axis_s;
175
176         end process;
177
178 end Behavioral;