OpenCores
URL https://opencores.org/ocsvn/ws2812/ws2812/trunk

Subversion Repositories ws2812

[/] [ws2812/] [trunk/] [rtl/] [VHDL/] [rgb_pixel_pack.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jclaytons
--------------------------------------------------------------------------
2
-- Package of dds components
3
--
4
--
5
 
6
library ieee;
7
use ieee.std_logic_1164.all;
8
use ieee.numeric_std.all;
9
 
10
package rgb_pixel_pack is
11
 
12
  component ws2812_LED_chain_driver
13
    generic (
14
      SYS_CLK_RATE : real; -- underlying clock rate
15
      ADR_BITS     : natural; -- Must equal or exceed BIT_WIDTH(N_LEDS)+2.
16
      N_LEDS       : natural  -- Number of LEDs in chain
17
    );
18
    port (
19
 
20
      -- System Clock, Reset and Clock Enable
21
      sys_rst_n  : in  std_logic;
22
      sys_clk    : in  std_logic;
23
      sys_clk_en : in  std_logic;
24
 
25
      -- Selection of color information
26
      c_adr_o    : out unsigned(ADR_BITS-1 downto 0);
27
      c_dat_i    : in  unsigned(7 downto 0);
28
 
29
      -- Output
30
      sdat_o     : out std_logic
31
    );
32
  end component;
33
 
34
  component lpd8806_LED_chain_driver
35
    generic (
36
      SCLK_FREQ    : real;    -- Desired lpd8806 serial clock frequency
37
      UPDATE_FREQ  : real;    -- Desired LED chain update frequency
38
      SYS_CLK_RATE : real;    -- underlying clock rate
39
      N_LEDS       : integer  -- Number of LEDs in chain
40
    );
41
    port (
42
 
43
      -- System Clock, Reset and Clock Enable
44
      sys_rst_n  : in  std_logic;
45
      sys_clk    : in  std_logic;
46
      sys_clk_en : in  std_logic;
47
 
48
      -- Selection of color information
49
      c_adr_o    : out unsigned(7 downto 0);
50
      c_dat_i    : in  unsigned(6 downto 0);
51
 
52
      -- Output
53
      sclk_o     : out std_logic;
54
      sdat_o     : out std_logic
55
    );
56
  end component;
57
 
58
  component spi_byte_writer
59
    generic (
60
      SCLK_FREQ    : real;    -- Desired lpd8806 serial clock frequency
61
      SYS_CLK_RATE : real     -- underlying clock rate
62
    );
63
    port (
64
 
65
      -- System Clock, Reset and Clock Enable
66
      sys_rst_n  : in  std_logic;
67
      sys_clk    : in  std_logic;
68
      sys_clk_en : in  std_logic;
69
 
70
      -- Data to send.
71
      sel_i      : in  std_logic;
72
      we_i       : in  std_logic;
73
      dat_i      : in  unsigned(7 downto 0);
74
 
75
      -- Output
76
      ssel_o     : out std_logic;
77
      sclk_o     : out std_logic;
78
      sdat_o     : out std_logic
79
    );
80
  end component;
81
 
82
end rgb_pixel_pack;
83
 
84
package body rgb_pixel_pack is
85
end rgb_pixel_pack;
86
 
87
-------------------------------------------------------------------------------
88
-- WS2812 "GRB" LED chain driver module
89
-------------------------------------------------------------------------------
90
--
91
-- Author: John Clayton
92
-- Update: Oct. 19, 2013 Started Coding, wrote description.
93
--
94
-- Description
95
-------------------------------------------------------------------------------
96
-- This module outputs a serial stream of NRZ data pulses which
97
-- are intended for driving a chain of WS2812 LED PWM driver ICs.
98
-- Actually, the WS2811 is the driver as a separate IC, and the WS2812 is
99
-- a complete RGB LED pixel with the driver built right in.  As costs drop
100
-- the popularity of this device is rising.
101
--
102
-- The datasheet seems to indicate some very specific timing requirements.
103
--
104
-- A '1' bit is apparently 0.35us high, followed by 0.8us low.
105
-- A '0' bit is apparently 0.7us high, followed by 0.6us low.
106
--
107
-- The datasheet also states that Th+Tl = 1.25us +/- 600 ns.
108
--
109
-- Well, based on that, this module chooses to use 1.25 microseconds
110
-- per bit time, which corresponds to 800kbps.  Internally, the system clock
111
-- rate is divided by 800000, and the result is the number of clock cycles
112
-- per bit available for creating the serial bitstream.
113
--
114
-- Then, constants are determined based on CLKS_PER_BIT according to the
115
-- following formulae:
116
--
117
--   CLKS_T0h = 0.28*CLKS_PER_BIT
118
--   CLKS_T1h = 0.54*CLKS_PER_BIT
119
--
120
-- This means that the timing will be closer or farther from ideal,
121
-- depending on the SYS_CLK_RATE.  For example:
122
--
123
--   Fsys_clk = 50 MHz
124
--   CLKS_PER_BIT = 62.5 which is rounded down to 62.
125
--   CLKS_T0h = 17.36 which is rounded down to 17.
126
--   CLKS_T1h = 33.48 which is rounded down to 33.
127
--   This leaves 45 clocks for the T0l time.
128
--   This leaves 29 clocks for the T1l time.
129
--
130
--   For this example, the bit time is 1.24us.
131
--   The T0h is 0.34us and T0l is 0.9us.
132
--   The T1h is 0.66us and T1l is 0.58us.
133
--
134
-- The lower the SYS_CLK_RATE, the tougher it is to meet the stated timing
135
-- requirements of the WS2812 device.  Using this scheme, the lowest clock
136
-- rate supported is 20 MHz.
137
--
138
-- The LEDs are driven with 24-bit color, that is 8 bits for red
139
-- intensity, 8 bits for green intensity and 8 bits for blue intensity.
140
--
141
-- I stopped short of calling it an "RGB LED driver" since WS2811/WS2812
142
-- receives the data in the order "GRB."  The ordering of the color
143
-- bits should not really matter anyway, so let's just be very accepting,
144
-- shall we not?
145
--
146
-- After the entire sequence of serial bits is driven out for updating the
147
-- GRB colors of the LEDs, then a reset interval of RESET_CLKS is given,
148
-- where RESET_CLKS is set by constants.
149
--
150
-- Interestingly, it seems that sending extra color information will not
151
-- affect the LED string in a negative way.  So, for example, if there
152
-- are only eight devices in the string, and the module is configured to
153
-- send out data for 10 devices, then the first eight devices will run
154
-- just fine.
155
--
156
-- Yes, that is correct, the LEDs closest to the source of sdat_o get lit
157
-- first, then they become "passthrough" so that the next one gets lit, and
158
-- so forth.
159
--
160
-- This module latches color information from an external source.
161
-- It provides the c_adr_o signal to specify which information
162
-- should be selected.  In this way, the module can be used with a variable
163
-- numbers of WS2811/WS2812 devices in the chain.
164
--
165
-- Just to keep things on an even keel, the c_adr_o address
166
-- advances according to the following pattern:
167
--
168
-- 0,1,2,4,5,6,8,9,A,C,D,E...
169
--
170
-- What is happening is that one address per LED is getting skipped
171
-- or "wasted" in order to start with each LEDs green value on an
172
-- even multiple N*4, where N is the LED number, beginning with zero
173
-- for the "zeroth" LED.  Then the red values are at N*4+1, while
174
-- the blue values are at N*4+2.  The N*4+3 values are simply skipped.
175
-- Isn't that super organized?
176
--
177
-- This unit runs continuously, the only way to stop it is to lower
178
-- the sys_clk_en input.
179
--
180
 
181
 
182
library IEEE;
183
use IEEE.STD_LOGIC_1164.ALL;
184
use IEEE.NUMERIC_STD.ALL;
185
use IEEE.MATH_REAL.ALL;
186
 
187
library work;
188
use work.dds_pack.all;
189
use work.convert_pack.all;
190
 
191
  entity ws2812_LED_chain_driver is
192
    generic (
193
      SYS_CLK_RATE : real := 50000000.0; -- underlying clock rate
194
      ADR_BITS     : natural := 8; -- Must equal or exceed BIT_WIDTH(N_LEDS)+2.
195
      N_LEDS       : natural := 8  -- Number of LEDs in chain
196
    );
197
    port (
198
 
199
      -- System Clock, Reset and Clock Enable
200
      sys_rst_n  : in  std_logic;
201
      sys_clk    : in  std_logic;
202
      sys_clk_en : in  std_logic;
203
 
204
      -- Selection of color information
205
      c_adr_o    : out unsigned(ADR_BITS-1 downto 0);
206
      c_dat_i    : in  unsigned(7 downto 0);
207
 
208
      -- Output
209
      sdat_o     : out std_logic
210
    );
211
    end ws2812_LED_chain_driver;
212
 
213
architecture beh of ws2812_LED_chain_driver is
214
 
215
-- Constants
216
constant LED_BIT_RATE   : real := 800000.0;
217
constant CLKS_PER_BIT   : natural := integer(floor(SYS_CLK_RATE/LED_BIT_RATE));
218
constant CLKS_T0_H      : natural := integer(floor(0.28*SYS_CLK_RATE/LED_BIT_RATE));
219
constant CLKS_T1_H      : natural := integer(floor(0.54*SYS_CLK_RATE/LED_BIT_RATE));
220
constant SUB_COUNT_BITS : natural := bit_width(CLKS_PER_BIT);
221
constant STRING_BYTES   : natural := 3*N_LEDS;
222
constant RESET_TIME     : real := 0.000050; -- "time" data type could have been used...
223
constant RESET_BCOUNT   : natural := integer(floor(RESET_TIME*LED_BIT_RATE));
224
constant RESET_BITS     : natural := timer_width(RESET_BCOUNT);
225
 
226
-- Signals
227
signal reset_count : unsigned(RESET_BITS-1 downto 0);
228
signal sub_count   : unsigned(SUB_COUNT_BITS-1 downto 0);
229
signal bit_count   : unsigned(2 downto 0);
230
signal byte_count  : unsigned(bit_width(STRING_BYTES)-1 downto 0);
231
signal c_adr       : unsigned(ADR_BITS-1 downto 0);
232
signal c_dat       : unsigned(7 downto 0);
233
 
234
-----------------------------------------------------------------------------
235
begin
236
 
237
  c_adr_proc: Process(sys_rst_n,sys_clk)
238
  begin
239
    if (sys_rst_n = '0') then
240
      reset_count <= to_unsigned(RESET_BCOUNT,reset_count'length);
241
      sub_count  <= (others=>'0');
242
      byte_count <= (others=>'0');
243
      c_adr      <= (others=>'0');
244
      c_dat      <= (others=>'0');
245
      bit_count  <= (others=>'0');
246
    elsif (sys_clk'event and sys_clk='1') then
247
      if (sys_clk_en='1') then
248
        -- Sub count just keeps going all the time, during reset
249
        -- and during data transition.
250
        sub_count <= sub_count+1;
251
        if (sub_count=CLKS_PER_BIT-1) then
252
          sub_count <= (others=>'0');
253
        end if;
254
 
255
        -- Reset count decrements until reaching one, then
256
        -- it is set to zero while data is shifted out.
257
        -- It decrements once for each bit time.
258
        if (reset_count>0) then
259
          if (sub_count=CLKS_PER_BIT-1) then
260
            reset_count <= reset_count-1;
261
          end if;
262
        end if;
263
 
264
        -- When reset count reaches zero, color data shifting occurs
265
        if (reset_count>0) then
266
          c_adr <= (others=>'0');
267
          if (reset_count=1 and sub_count=CLKS_PER_BIT-1) then
268
            c_adr <= c_adr+1; -- Data from first address is loaded during reset time...
269
          end if;
270
          c_dat <= c_dat_i;
271
        else
272
          if (sub_count=CLKS_PER_BIT-1) then
273
            c_dat <= c_dat(c_dat'length-2 downto 0) & '0'; -- shift
274
            bit_count <= bit_count+1;
275
            if (bit_count=7) then
276
              c_dat <= c_dat_i;
277
              if (c_adr(1 downto 0)="10") then
278
                c_adr <= c_adr+2;
279
                if (byte_count=STRING_BYTES-1) then
280
                  byte_count <= (others=>'0');
281
                  reset_count <= to_unsigned(RESET_BCOUNT,reset_count'length);
282
                else
283
                  byte_count <= byte_count+1;
284
                end if;
285
              else
286
                c_adr <= c_adr+1;
287
              end if;
288
            end if;
289
          end if;
290
        end if;
291
      end if;
292
    end if; -- sys_clk
293
  end process;
294
  sdat_o <= '0' when (reset_count>0) else
295
            '1' when (c_dat(7)='1') and (sub_count<CLKS_T1_H) else
296
            '1' when (sub_count<CLKS_T0_H) else
297
            '0';
298
  c_adr_o <= c_adr;
299
 
300
end beh;
301
 
302
 
303
-------------------------------------------------------------------------------
304
-- LPD8806 "GRB" LED chain driver module
305
-------------------------------------------------------------------------------
306
--
307
-- Author: John Clayton
308
-- Update: Apr.  8, 2013 Started Coding, wrote description.
309
--         Apr. 10, 2013 Simulated and tested in hardware.
310
--
311
-- Description
312
-------------------------------------------------------------------------------
313
-- This module outputs a serial stream of clock and data pulses which
314
-- are intended for driving a chain of LPD8806 LED PWM driver ICs.
315
--
316
-- This type of LED driver is commonly sold pre-built into strips
317
-- of LEDs, with each LPD8806 circuit driving two multi-color LEDs.
318
--
319
-- The LEDs are driven with 21-bit color, that is 7 bits for red
320
-- intensity, 7 bits for green intensity and 7 bits for blue intensity.
321
--
322
-- I stopped short of calling it an "RGB LED driver" since lpd8806
323
-- receives the data in the order "GRB."  The ordering of the color
324
-- bits should not really matter anyway, so just be happy, OK?
325
--
326
-- The first bit, the MSB, is set for updating the LED colors, and cleared
327
-- for resetting the drivers.  Therefore, after each sequence of color
328
-- information bits, about 24 bits of zero are sent out to reset
329
-- everything in order to be ready for the next update.
330
--
331
-- This module generates its own serial bit clock by using a DDS based
332
-- on the underlying system clock rate.  It has been suggested that
333
-- 2 MHz is a good number, although I'll bet many other speeds will
334
-- also work, both higher and lower.
335
--
336
-- Another DDS generates the update rate pulse, which kicks off
337
-- the updating process.  Beware, if one sets the update rate too
338
-- high, it may become impossible to transmit all the required color
339
-- bits, and so the LEDs at the end of the chain may get left out
340
-- of the process!
341
--
342
-- Yes, that is correct, the LEDs closest to the source of SCLK
343
-- and SDAT get lit first, then they become "passthrough" so that
344
-- the next one gets set, and so forth.
345
--
346
-- This module latches color information from an external source.
347
-- It provides the c_adr_o signal to specify which information
348
-- should be selected.  In this way, the module can be used with
349
-- different numbers of drivers and LED pairs in the strip.
350
--
351
-- Just to keep things on an even keel, the c_adr_o address
352
-- advances according to the following pattern:
353
--
354
-- 0,1,2,4,5,6,8,9,A,C,D,E...
355
--
356
-- What is happening is that one address per LED is getting skipped
357
-- or "wasted" in order to start with each LEDs green value on an
358
-- even multiple N*4, where N is the LED number, beginning with zero
359
-- for the "zeroth" LED.  Then the red values are at N*4+1, while
360
-- the blue values are at N*4+2.  The N*4+3 values are simply skipped.
361
-- Isn't that super organized?
362
--
363
--
364
 
365
 
366
library IEEE;
367
use IEEE.STD_LOGIC_1164.ALL;
368
use IEEE.NUMERIC_STD.ALL;
369
use IEEE.MATH_REAL.ALL;
370
 
371
library work;
372
use work.dds_pack.all;
373
 
374
  entity lpd8806_LED_chain_driver is
375
    generic (
376
      SCLK_FREQ    : real;    -- Desired lpd8806 serial clock frequency
377
      UPDATE_FREQ  : real;    -- Desired LED chain update frequency
378
      SYS_CLK_RATE : real;    -- underlying clock rate
379
      N_LEDS       : integer  -- Number of LEDs in chain
380
    );
381
    port (
382
 
383
      -- System Clock, Reset and Clock Enable
384
      sys_rst_n  : in  std_logic;
385
      sys_clk    : in  std_logic;
386
      sys_clk_en : in  std_logic;
387
 
388
      -- Selection of color information
389
      c_adr_o    : out unsigned(7 downto 0);
390
      c_dat_i    : in  unsigned(6 downto 0);
391
 
392
      -- Output
393
      sclk_o     : out std_logic;
394
      sdat_o     : out std_logic
395
    );
396
    end lpd8806_LED_chain_driver;
397
 
398
architecture beh of lpd8806_LED_chain_driver is
399
 
400
-- Constants
401
constant N_ZERO_BYTES : natural := 3;
402
 
403
-- Signals
404
signal sclk            : std_logic;
405
signal sclk_pulse      : std_logic;
406
signal update_pulse    : std_logic;
407
signal bit_count       : unsigned(3 downto 0);
408
signal byte_count      : unsigned(7 downto 0); -- Widen for chains of 64+ LEDs.
409
signal c_adr           : unsigned(7 downto 0); -- Widen for chains of 64+ LEDs.
410
signal c_dat           : unsigned(7 downto 0);
411
 
412
-----------------------------------------------------------------------------
413
begin
414
 
415
  c_adr_proc: Process(sys_rst_n,sys_clk)
416
  begin
417
    if (sys_rst_n = '0') then
418
      byte_count <= (others=>'0');
419
      c_adr      <= (others=>'0');
420
      c_dat      <= (others=>'0');
421
      bit_count  <= (others=>'0');
422
    elsif (sys_clk'event and sys_clk='1') then
423
      if (sys_clk_en='1') then
424
        if (byte_count=0) then
425
          c_adr <= (others=>'0');
426
        end if;
427
        if (byte_count>0 and sclk_pulse='1') then
428
          bit_count <= bit_count-1;
429
          if (bit_count<8) then
430
            c_dat <= c_dat(6 downto 0) & '0'; -- Default is to shift color data
431
            if (bit_count=0) then
432
              byte_count <= byte_count-1;
433
              bit_count  <= to_unsigned(7,bit_count'length);
434
              -- Set color data MSB appropriately
435
              if (byte_count<=4) then
436
                c_dat <= (others=>'0');
437
              else
438
                c_dat <= '1' & c_dat_i;
439
              end if;
440
              -- Cause c_adr to skip every address.ending in "11"
441
              if (c_adr(1 downto 0)="10") then
442
                c_adr <= c_adr+2;
443
              else
444
                c_adr <= c_adr+1;
445
              end if;
446
            end if;
447
          end if;
448
        end if;
449
        -- Update pulse gets highest priority
450
        if (update_pulse='1') then
451
          byte_count <= to_unsigned(N_LEDS*3+1+N_ZERO_BYTES,byte_count'length);
452
          if (sclk_pulse='1') then
453
            bit_count  <= to_unsigned(7,bit_count'length);
454
          else
455
            bit_count  <= to_unsigned(8,bit_count'length); -- means "pending"
456
          end if;
457
          c_dat      <= '1' & c_dat_i;
458
          c_adr      <= c_adr+1;
459
        end if;
460
      end if;
461
    end if; -- sys_clk
462
  end process;
463
  sdat_o <= c_dat(7) when (byte_count>0 and bit_count<8) else '0';
464
  c_adr_o <= c_adr;
465
 
466
  -------------------------
467
  -- Update pulse generation
468
  update_gen: dds_constant_squarewave
469
    generic map(
470
      OUTPUT_FREQ  => UPDATE_FREQ,  -- Desired output frequency
471
      SYS_CLK_RATE => SYS_CLK_RATE, -- underlying clock rate
472
      ACC_BITS     => 24 -- Bit width of DDS phase accumulator
473
    )
474
    port map(
475
 
476
      sys_rst_n    => sys_rst_n,
477
      sys_clk      => sys_clk,
478
      sys_clk_en   => sys_clk_en,
479
 
480
      -- Output
481
      pulse_o      => update_pulse,
482
      squarewave_o => open
483
    );
484
 
485
  -------------------------
486
  -- Serial clock generation
487
  sclk_gen: dds_constant_squarewave
488
    generic map(
489
      OUTPUT_FREQ  => SCLK_FREQ,   -- Desired output frequency
490
      SYS_CLK_RATE => SYS_CLK_RATE, -- underlying clock rate
491
      ACC_BITS     => 16 -- Bit width of DDS phase accumulator
492
    )
493
    port map(
494
 
495
      sys_rst_n    => sys_rst_n,
496
      sys_clk      => sys_clk,
497
      sys_clk_en   => sys_clk_en,
498
 
499
      -- Output
500
      pulse_o      => sclk_pulse,
501
      squarewave_o => sclk
502
    );
503
  sclk_o <= not sclk when (byte_count>0 and bit_count<8) else '0';
504
 
505
end beh;
506
 
507
 
508
-------------------------------------------------------------------------------
509
-- SPI byte writer module
510
-------------------------------------------------------------------------------
511
--
512
-- Author: John Clayton
513
-- Update: Apr.  8, 2013 Started Coding, wrote description.
514
--
515
-- Description
516
-------------------------------------------------------------------------------
517
-- I conceived of this module while debugging a serial driver for a
518
-- string of LPD8806 LED drivers.  It essentially latches the input
519
-- data, and sends it out serially at the desired rate.  When the byte
520
-- is fully transmitted, it stops and waits for the next byte.
521
--
522
-- The output clock is gated by ssel_o.  If you need a continuous
523
-- clock, please ungate it yourself.
524
--
525
-- Unlike with asynchronous data which shift out the lsb first, this
526
-- unit shifts out the msb first.
527
--
528
 
529
 
530
library IEEE;
531
use IEEE.STD_LOGIC_1164.ALL;
532
use IEEE.NUMERIC_STD.ALL;
533
use IEEE.MATH_REAL.ALL;
534
 
535
library work;
536
use work.dds_pack.all;
537
 
538
  entity spi_byte_writer is
539
    generic (
540
      SCLK_FREQ    : real;    -- Desired lpd8806 serial clock frequency
541
      SYS_CLK_RATE : real     -- underlying clock rate
542
    );
543
    port (
544
 
545
      -- System Clock, Reset and Clock Enable
546
      sys_rst_n  : in  std_logic;
547
      sys_clk    : in  std_logic;
548
      sys_clk_en : in  std_logic;
549
 
550
      -- Data to send.
551
      sel_i      : in  std_logic;
552
      we_i       : in  std_logic;
553
      dat_i      : in  unsigned(7 downto 0);
554
 
555
      -- Output
556
      ssel_o     : out std_logic;
557
      sclk_o     : out std_logic;
558
      sdat_o     : out std_logic
559
    );
560
    end spi_byte_writer;
561
 
562
architecture beh of spi_byte_writer is
563
 
564
-- Signals
565
signal sclk            : std_logic;
566
signal sclk_pulse      : std_logic;
567
signal ssel            : std_logic;
568
signal sdat            : unsigned(7 downto 0);
569
signal bit_count       : unsigned(3 downto 0);
570
 
571
-----------------------------------------------------------------------------
572
begin
573
 
574
  spi_write_proc: Process(sys_rst_n,sys_clk)
575
  begin
576
    if (sys_rst_n = '0') then
577
      sdat      <= (others=>'0');
578
      bit_count <= (others=>'0');
579
    elsif (sys_clk'event and sys_clk='1') then
580
      if (sys_clk_en='1') then
581
        if (sclk_pulse='1') then
582
          if (bit_count>0) then
583
            bit_count <= bit_count-1;
584
          end if;
585
          if ssel='1' then
586
            sdat <= sdat(6 downto 0) & '0';
587
          end if;
588
        elsif (sel_i='1' and we_i='1') then
589
          if (sclk_pulse='1') then
590
            bit_count  <= to_unsigned(8,bit_count'length);
591
          else
592
            bit_count  <= to_unsigned(9,bit_count'length); -- means "pending"
593
          end if;
594
          sdat <= dat_i;
595
        end if;
596
      end if;
597
    end if; -- sys_clk
598
  end process;
599
  sdat_o <= sdat(7) when ssel='1' else '0';
600
 
601
  -------------------------
602
  -- Serial clock generation
603
  sclk_gen: dds_constant_squarewave
604
    generic map(
605
      OUTPUT_FREQ  => SCLK_FREQ,   -- Desired output frequency
606
      SYS_CLK_RATE => SYS_CLK_RATE, -- underlying clock rate
607
      ACC_BITS     => 16 -- Bit width of DDS phase accumulator
608
    )
609
    port map(
610
 
611
      sys_rst_n    => sys_rst_n,
612
      sys_clk      => sys_clk,
613
      sys_clk_en   => sys_clk_en,
614
 
615
      -- Output
616
      pulse_o      => sclk_pulse,
617
      squarewave_o => sclk
618
    );
619
  sclk_o <= not sclk when ssel='1' else '0';
620
  ssel   <= '1'  when (bit_count<9 and bit_count>0) else '0';
621
  ssel_o <= ssel;
622
 
623
end beh;
624
 
625
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.