]> rtime.felk.cvut.cz Git - fpga/zynq/canbench-sw.git/blob - system/ip/spi_leds_and_enc_1.0/hdl/spi_leds_and_enc_v1_0.vhd
microzed_apo: Correct JX1_LVDS_21_N pin assignment on FPGA_IO header.
[fpga/zynq/canbench-sw.git] / system / ip / spi_leds_and_enc_1.0 / hdl / spi_leds_and_enc_v1_0.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4
5 entity spi_leds_and_enc_v1_0 is
6         generic (
7                 -- Users to add parameters here
8
9                 -- User parameters ends
10                 -- Do not modify the parameters beyond this line
11
12
13                 -- Parameters of Axi Slave Bus Interface S00_AXI
14                 C_S00_AXI_DATA_WIDTH    : integer       := 32;
15                 C_S00_AXI_ADDR_WIDTH    : integer       := 6
16         );
17         port (
18                 -- Users to add ports here
19                 spi_led_reset   : out std_logic;
20                 spi_led_clk     : out std_logic;
21                 spi_led_cs      : out std_logic;
22                 spi_led_data    : out std_logic;
23                 spi_led_encin   : in std_logic;
24                 -- User ports ends
25                 -- Do not modify the ports beyond this line
26
27
28                 -- Ports of Axi Slave Bus Interface S00_AXI
29                 s00_axi_aclk    : in std_logic;
30                 s00_axi_aresetn : in std_logic;
31                 s00_axi_awaddr  : in std_logic_vector(C_S00_AXI_ADDR_WIDTH-1 downto 0);
32                 s00_axi_awprot  : in std_logic_vector(2 downto 0);
33                 s00_axi_awvalid : in std_logic;
34                 s00_axi_awready : out std_logic;
35                 s00_axi_wdata   : in std_logic_vector(C_S00_AXI_DATA_WIDTH-1 downto 0);
36                 s00_axi_wstrb   : in std_logic_vector((C_S00_AXI_DATA_WIDTH/8)-1 downto 0);
37                 s00_axi_wvalid  : in std_logic;
38                 s00_axi_wready  : out std_logic;
39                 s00_axi_bresp   : out std_logic_vector(1 downto 0);
40                 s00_axi_bvalid  : out std_logic;
41                 s00_axi_bready  : in std_logic;
42                 s00_axi_araddr  : in std_logic_vector(C_S00_AXI_ADDR_WIDTH-1 downto 0);
43                 s00_axi_arprot  : in std_logic_vector(2 downto 0);
44                 s00_axi_arvalid : in std_logic;
45                 s00_axi_arready : out std_logic;
46                 s00_axi_rdata   : out std_logic_vector(C_S00_AXI_DATA_WIDTH-1 downto 0);
47                 s00_axi_rresp   : out std_logic_vector(1 downto 0);
48                 s00_axi_rvalid  : out std_logic;
49                 s00_axi_rready  : in std_logic
50         );
51 end spi_leds_and_enc_v1_0;
52
53 architecture arch_imp of spi_leds_and_enc_v1_0 is
54
55         -- component declaration
56         component spi_leds_and_enc_v1_0_S00_AXI is
57                 generic (
58                 C_S_AXI_DATA_WIDTH      : integer       := 32;
59                 C_S_AXI_ADDR_WIDTH      : integer       := 6
60                 );
61                 port (
62                 output_led_line : out std_logic_vector(31 downto 0);
63                 output_led_rgb1 : out std_logic_vector(23 downto 0);
64                 output_led_rgb2 : out std_logic_vector(23 downto 0);
65                 output_led_direct : out std_logic_vector(7 downto 0);
66                 output_kbd_direct : out std_logic_vector(3 downto 0);
67
68                 in_enc_direct : in std_logic_vector(8 downto 0);
69                 in_kbd_direct : in std_logic_vector(3 downto 0);
70                 in_enc_8bit : in std_logic_vector(23 downto 0);
71                 in_enc_buttons : in std_logic_vector(2 downto 0);
72
73                 S_AXI_ACLK      : in std_logic;
74                 S_AXI_ARESETN   : in std_logic;
75                 S_AXI_AWADDR    : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
76                 S_AXI_AWPROT    : in std_logic_vector(2 downto 0);
77                 S_AXI_AWVALID   : in std_logic;
78                 S_AXI_AWREADY   : out std_logic;
79                 S_AXI_WDATA     : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
80                 S_AXI_WSTRB     : in std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0);
81                 S_AXI_WVALID    : in std_logic;
82                 S_AXI_WREADY    : out std_logic;
83                 S_AXI_BRESP     : out std_logic_vector(1 downto 0);
84                 S_AXI_BVALID    : out std_logic;
85                 S_AXI_BREADY    : in std_logic;
86                 S_AXI_ARADDR    : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
87                 S_AXI_ARPROT    : in std_logic_vector(2 downto 0);
88                 S_AXI_ARVALID   : in std_logic;
89                 S_AXI_ARREADY   : out std_logic;
90                 S_AXI_RDATA     : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
91                 S_AXI_RRESP     : out std_logic_vector(1 downto 0);
92                 S_AXI_RVALID    : out std_logic;
93                 S_AXI_RREADY    : in std_logic
94                 );
95         end component spi_leds_and_enc_v1_0_S00_AXI;
96
97         component spi_leds_and_enc_v1_0_spi_fsm is
98                 generic (
99                 data_width      : integer       := 32;
100                 spi_clkdiv      : integer       := 10
101                 );
102                 port (
103                 reset_in        : in std_logic;
104
105                 clk_in          : in std_logic;
106                 clk_en          : in std_logic;
107
108                 spi_clk         : out std_logic;
109                 spi_cs          : out std_logic;
110                 spi_mosi        : out std_logic;
111                 spi_miso        : in std_logic;
112
113                 tx_data         : in std_logic_vector(data_width-1 downto 0);
114                 rx_data         : out std_logic_vector(data_width-1 downto 0);
115
116                 trasfer_rq      : in std_logic;
117                 transfer_ready  : out std_logic
118                 );
119         end component;
120
121         component dff3cke is
122                 port (
123                 clk_i    : in std_logic;
124                 clk_en   : in std_logic;
125                 d_i      : in std_logic;
126                 q_o      : out std_logic;
127                 ch_o     : out std_logic;
128                 ch_1ck_o : out std_logic
129                 );
130         end component;
131
132         component qcounter_nbit is
133                 generic (
134                 bitwidth: integer := 32
135                 );
136                 port (
137                 clock: in std_logic;
138                 reset: in std_logic;
139                 a0, b0: in std_logic;
140                 qcount: out std_logic_vector (bitwidth - 1 downto 0);
141                 a_rise, a_fall, b_rise, b_fall, ab_event: out std_logic;
142                 ab_error: out std_logic
143                 );
144         end component;
145
146         component cnt_div is
147                 generic (
148                 cnt_width_g : natural := 4
149                 );
150                 port
151                 (
152                 clk_i     : in std_logic;                               --clk to divide
153                 en_i      : in std_logic;                               --enable bit?
154                 reset_i   : in std_logic;                               --asynch. reset
155                 ratio_i   : in std_logic_vector(cnt_width_g-1 downto 0);--initial value
156                 q_out_o   : out std_logic                               --generates puls when counter underflows
157                 );
158         end component;
159
160         component pulse_gen is
161                 generic (
162                 duration_width_g : natural := 4
163                 );
164                 port (
165                 clk_i      : in std_logic;                              --clk to divide
166                 en_i       : in std_logic;                              --enable bit?
167                 reset_i    : in std_logic;                              --asynch. reset
168                 trigger_i  : in std_logic;                              --start to generate pulse
169                 duration_i : in std_logic_vector(duration_width_g-1 downto 0);--duration/interval of the pulse
170                 q_out_o    : out std_logic                              --generates pulse for given duration
171                 );
172         end component;
173
174         constant spi_data_width : integer := 48;
175         constant spi_clk_div : integer := 10;
176         constant enc_number : integer := 3;
177         constant pwm_width : integer := 8;
178         constant pwm_ratio : std_logic_vector(pwm_width-1 downto 0) :=
179                              std_logic_vector(to_unsigned(2 ** pwm_width - 1, pwm_width));
180
181         signal fsm_clk : std_logic;
182         signal fsm_rst : std_logic;
183         signal spi_rx_data : std_logic_vector(spi_data_width-1 downto 0);
184         signal spi_tx_data : std_logic_vector(spi_data_width-1 downto 0);
185         signal spi_transfer_ready : std_logic;
186
187         signal spi_out_rgb1 : std_logic_vector(2 downto 0);
188         signal spi_out_rgb2 : std_logic_vector(2 downto 0);
189
190         signal spi_out_led3 : std_logic;
191         signal spi_out_led4 : std_logic;
192
193         signal output_led_line : std_logic_vector(31 downto 0);
194         signal output_led_rgb1 : std_logic_vector(23 downto 0);
195         signal output_led_rgb2 : std_logic_vector(23 downto 0);
196         signal output_led_direct : std_logic_vector(7 downto 0);
197         signal output_kbd_direct : std_logic_vector(3 downto 0);
198
199         signal in_enc_direct : std_logic_vector(8 downto 0);
200         signal in_kbd_direct : std_logic_vector(3 downto 0);
201         signal in_enc_8bit : std_logic_vector(23 downto 0);
202         signal in_enc_buttons : std_logic_vector(2 downto 0);
203
204         signal enc_cha : std_logic_vector(enc_number downto 1);
205         signal enc_chb : std_logic_vector(enc_number downto 1);
206         signal enc_sw : std_logic_vector(enc_number downto 1);
207
208         signal enc_cha_filt : std_logic_vector(enc_number downto 1);
209         signal enc_chb_filt : std_logic_vector(enc_number downto 1);
210         signal enc_sw_filt : std_logic_vector(enc_number downto 1);
211         signal enc_sw_changed : std_logic_vector(enc_number downto 1);
212         signal enc_pos_changed : std_logic_vector(enc_number downto 1);
213
214         signal pwm_cycle_start : std_logic;
215         signal pwm_rgb1_sig : std_logic_vector(2 downto 0);
216         signal pwm_rgb2_sig : std_logic_vector(2 downto 0);
217
218 begin
219
220 -- Instantiation of Axi Bus Interface S00_AXI
221 spi_leds_and_enc_v1_0_S00_AXI_inst : spi_leds_and_enc_v1_0_S00_AXI
222         generic map (
223                 C_S_AXI_DATA_WIDTH      => C_S00_AXI_DATA_WIDTH,
224                 C_S_AXI_ADDR_WIDTH      => C_S00_AXI_ADDR_WIDTH
225         )
226         port map (
227                 output_led_line => output_led_line,
228                 output_led_rgb1 => output_led_rgb1,
229                 output_led_rgb2 => output_led_rgb2,
230                 output_led_direct => output_led_direct,
231                 output_kbd_direct => output_kbd_direct,
232
233                 in_enc_direct => in_enc_direct,
234                 in_kbd_direct => in_kbd_direct,
235                 in_enc_8bit => in_enc_8bit,
236                 in_enc_buttons => in_enc_buttons,
237
238                 S_AXI_ACLK      => s00_axi_aclk,
239                 S_AXI_ARESETN   => s00_axi_aresetn,
240                 S_AXI_AWADDR    => s00_axi_awaddr,
241                 S_AXI_AWPROT    => s00_axi_awprot,
242                 S_AXI_AWVALID   => s00_axi_awvalid,
243                 S_AXI_AWREADY   => s00_axi_awready,
244                 S_AXI_WDATA     => s00_axi_wdata,
245                 S_AXI_WSTRB     => s00_axi_wstrb,
246                 S_AXI_WVALID    => s00_axi_wvalid,
247                 S_AXI_WREADY    => s00_axi_wready,
248                 S_AXI_BRESP     => s00_axi_bresp,
249                 S_AXI_BVALID    => s00_axi_bvalid,
250                 S_AXI_BREADY    => s00_axi_bready,
251                 S_AXI_ARADDR    => s00_axi_araddr,
252                 S_AXI_ARPROT    => s00_axi_arprot,
253                 S_AXI_ARVALID   => s00_axi_arvalid,
254                 S_AXI_ARREADY   => s00_axi_arready,
255                 S_AXI_RDATA     => s00_axi_rdata,
256                 S_AXI_RRESP     => s00_axi_rresp,
257                 S_AXI_RVALID    => s00_axi_rvalid,
258                 S_AXI_RREADY    => s00_axi_rready
259         );
260
261         -- Add user logic here
262
263 spi_leds_and_enc_v1_0_spi_fsm_inst: spi_leds_and_enc_v1_0_spi_fsm
264         generic map (
265                 data_width => spi_data_width,
266                 spi_clkdiv => spi_clk_div
267         )
268         port map (
269                 reset_in => fsm_rst,
270                 clk_in => fsm_clk,
271                 clk_en => '1',
272
273                 spi_clk => spi_led_clk,
274                 spi_cs => spi_led_cs,
275                 spi_mosi => spi_led_data,
276                 spi_miso => spi_led_encin,
277
278                 tx_data => spi_tx_data,
279                 rx_data => spi_rx_data,
280
281                 trasfer_rq => '1',
282                 transfer_ready => spi_transfer_ready
283         );
284
285 cnt_div_inst: cnt_div
286         generic map (
287                 cnt_width_g => pwm_width
288         )
289         port map (
290                 clk_i => fsm_clk,
291                 en_i => spi_transfer_ready,
292                 reset_i => fsm_rst,
293                 ratio_i => pwm_ratio,
294                 q_out_o => pwm_cycle_start
295         );
296
297 irc_block: for i in enc_number downto 1 generate
298     filt_cha: dff3cke
299       port map (
300           clk_i => fsm_clk,
301           clk_en => spi_transfer_ready,
302           d_i => enc_cha(i),
303           q_o => enc_cha_filt(i),
304           ch_o => open,
305           ch_1ck_o => open
306         );
307     filt_chb: dff3cke
308       port map (
309           clk_i => fsm_clk,
310           clk_en => spi_transfer_ready,
311           d_i => enc_chb(i),
312           q_o => enc_chb_filt(i),
313           ch_o => open,
314           ch_1ck_o => open
315         );
316     filt_sw: dff3cke
317       port map (
318           clk_i => fsm_clk,
319           clk_en => spi_transfer_ready,
320           d_i => enc_sw(i),
321           q_o => enc_sw_filt(i),
322           ch_o => open,
323           ch_1ck_o => enc_sw_changed(i)
324         );
325     qcounter: qcounter_nbit
326       generic map (
327           bitwidth => 8
328         )
329       port map (
330           clock => fsm_clk,
331           reset => fsm_rst,
332           a0 => enc_cha_filt(i),
333           b0 => enc_chb_filt(i),
334           qcount => in_enc_8bit((3 - i) * 8 + 7 downto (3 - i) * 8),
335           a_rise => open,
336           a_fall => open,
337           b_rise => open,
338           b_fall => open,
339           ab_event => enc_pos_changed(i),
340           ab_error => open
341         );
342   end generate;
343
344 pwm_rgb1_block: for i in 2 downto 0 generate
345     pwm_rgb1: pulse_gen
346       generic map (
347           duration_width_g => pwm_width
348       )
349       port map (
350           clk_i => fsm_clk,
351           en_i => spi_transfer_ready,
352           reset_i => fsm_rst,
353           trigger_i => pwm_cycle_start,
354           duration_i => output_led_rgb1(i * 8 + 7 downto i * 8),
355           q_out_o => pwm_rgb1_sig(i)
356       );
357   end generate;
358
359 pwm_rgb2_block: for i in 2 downto 0 generate
360     pwm_rgb2: pulse_gen
361       generic map (
362           duration_width_g => pwm_width
363       )
364       port map (
365           clk_i => fsm_clk,
366           en_i => spi_transfer_ready,
367           reset_i => fsm_rst,
368           trigger_i => pwm_cycle_start,
369           duration_i => output_led_rgb2(i * 8 + 7 downto i * 8),
370           q_out_o => pwm_rgb2_sig(i)
371       );
372   end generate;
373
374         fsm_clk <= s00_axi_aclk;
375         fsm_rst <= not s00_axi_aresetn;
376
377 data_logic_process :process
378         begin
379                 wait until rising_edge (fsm_clk);
380                 if fsm_rst = '1' then
381                         spi_led_reset <= '1';
382                 elsif spi_transfer_ready = '1' then
383                         spi_led_reset <= '0';
384                 end if;
385         end process;
386
387         spi_tx_data(47) <= '0';
388         spi_tx_data(46 downto 44) <= spi_out_rgb1;
389         spi_tx_data(43 downto 42) <= (others => '0');
390         spi_tx_data(41) <= spi_out_led4;
391         spi_tx_data(40) <= spi_out_led3;
392         spi_tx_data(39 downto 8) <= output_led_line;
393         spi_tx_data(7) <= '0';
394         spi_tx_data(6 downto 3) <= not output_kbd_direct;
395         spi_tx_data(2 downto 0) <= spi_out_rgb2;
396
397         enc_chb(1) <= not spi_rx_data(4);
398         enc_sw(1) <= not spi_rx_data(5);
399         enc_cha(1) <= not spi_rx_data(6);
400
401         enc_chb(2) <= not spi_rx_data(11);
402         enc_sw(2) <= not spi_rx_data(12);
403         enc_cha(2) <= not spi_rx_data(13);
404
405         enc_chb(3) <= not spi_rx_data(8);
406         enc_sw(3) <= not spi_rx_data(9);
407         enc_cha(3) <= not spi_rx_data(10);
408
409         in_kbd_direct <= not spi_rx_data(3 downto 0);
410
411         in_enc_buttons(2) <= enc_sw_filt(1);
412         in_enc_buttons(1) <= enc_sw_filt(2);
413         in_enc_buttons(0) <= enc_sw_filt(3);
414
415         -- in_enc_8bit <= (others => '0');
416
417         in_enc_direct <= (8 => enc_sw(1), 7 => enc_chb(1), 6 => enc_cha(1),
418                           5 => enc_sw(2), 4 => enc_chb(2), 3 => enc_cha(2),
419                           2 => enc_sw(3), 1 => enc_chb(3), 0 => enc_cha(3));
420
421         -- output_led_rgb1 : out std_logic_vector(23 downto 0);
422         -- output_led_rgb2 : out std_logic_vector(23 downto 0);
423         -- output_led_direct : out std_logic_vector(7 downto 0);
424
425         spi_out_rgb1 <= output_led_direct(2 downto 0) or pwm_rgb1_sig;
426         spi_out_rgb2 <= output_led_direct(5 downto 3) or pwm_rgb2_sig;
427         spi_out_led3 <= output_led_direct(6);
428         spi_out_led4 <= output_led_direct(7);
429
430         -- User logic ends
431
432 end arch_imp;