Rev Author Line No. Line
3641 kaklik 1 -- this module transmit a given constant data when requested
2 -- and then signals done.
3 --
4 -- G_DATA has to contain also the address and the r/w bit
5 --
6 -- MSB of G_DATA will go first
7 -- P1DATA_P2DATA_P3DATA
8 --
9 -- version for multiple devices with different data
10  
11 library ieee;
12 use ieee.std_logic_1164.all;
13 use ieee.numeric_std.all;
14  
15 entity spi_master_transmit is
16 generic (
17 G_DATA1 : std_logic_vector;
18 G_DATA2 : std_logic_vector;
19 G_NUM_BITS_PACKET : integer;
20 G_NUM_PACKETS : integer;
21 G_NUM_BITS_PAUSE : integer
22 );
23 port (
24  
25 i_clk : in std_logic;
26 i_rst : in std_logic;
27  
28 o_done : out std_logic;
29  
30 -- selects which data to transfer. If '0', it transfers G_DATA1
31 i_data_selector : in std_logic;
32  
33 -- SPI ports:
34 o_n_ce : out std_logic_vector;
35 o_dout : out std_logic;
36 o_clk : out std_logic
37  
38 );
39  
40 end spi_master_transmit;
41  
42 architecture behavioral of spi_master_transmit is
43  
44 subtype t_pause_counter is integer range 0 to G_NUM_BITS_PAUSE;
45 signal s_pause_counter : t_pause_counter;
46 subtype t_bit_counter is integer range 0 to G_NUM_BITS_PACKET - 1;
47 signal s_bit_counter : t_bit_counter;
48 subtype t_packet_counter is integer range 0 to G_NUM_PACKETS;
49 signal s_packet_counter : t_packet_counter;
50 subtype t_device_counter is integer range 0 to o_n_ce'length - 1;
51 signal s_device_counter : t_device_counter;
52  
53 signal s_clk_inv : std_logic;
54  
55 --signal s_o_dout_d : std_logic;
56 signal s_o_clk_en : std_logic;
57  
58 constant C_DATALEN_PER_DEVICE : integer := G_NUM_BITS_PACKET*G_NUM_PACKETS;
59  
60 signal s_cs_out : std_logic_vector( o_n_ce'range );
61  
62 begin
63  
64 assert( G_DATA1'length = C_DATALEN_PER_DEVICE*o_n_ce'length ) report "The size of G_DATA1 does not match the number of devices and other generics." severity failure;
65 assert( G_DATA2'length = C_DATALEN_PER_DEVICE*o_n_ce'length ) report "The size of G_DATA2 does not match the number of devices and other generics." severity failure;
66  
67 -- inverted clock:
68 s_clk_inv <= not i_clk;
69  
70 -- output clock:
71 o_clk <= i_clk and s_o_clk_en;
72  
73 -- done:
74 o_done <= '1' when ( (i_rst = '0') and (s_packet_counter = 0) and (s_pause_counter = 0) and (s_bit_counter = 0 ) and (s_device_counter=0) ) else
75 '0';
76  
77 transmitter_process : process( s_clk_inv )
78 begin
79 if( rising_edge( s_clk_inv ) ) then
80 if( i_rst = '1' ) then
81 s_bit_counter <= 0;
82 s_pause_counter <= t_pause_counter'high;
83 s_packet_counter <= t_packet_counter'high;
84 s_device_counter <= t_device_counter'high;
85 s_cs_out( s_cs_out'low ) <= '0';
86 s_cs_out( s_cs_out'high downto s_cs_out'low+1 ) <= ( others => '1' );
87 o_n_ce <= ( o_n_ce'range => '1' );
88 o_dout <= '0';
89 s_o_clk_en <= '0';
90 elsif( s_bit_counter > 0 ) then
91 o_n_ce <= s_cs_out;
92 if( i_data_selector = '0' ) then
93 o_dout <= G_DATA1( s_bit_counter + s_packet_counter*G_NUM_BITS_PACKET - 1 + s_device_counter*C_DATALEN_PER_DEVICE ); -- here s_packet_counter points to the current packet and s_bit_counter is one bit behind, therefore the -1.
94 else
95 o_dout <= G_DATA2( s_bit_counter + s_packet_counter*G_NUM_BITS_PACKET - 1 + s_device_counter*C_DATALEN_PER_DEVICE );
96 end if;
97 s_bit_counter <= s_bit_counter - 1;
98 s_o_clk_en <= '1';
99 elsif( s_pause_counter > 0 ) then
100 o_n_ce <= ( o_n_ce'range => '1' );
101 s_pause_counter <= s_pause_counter - 1;
102 o_dout <= '0';
103 s_o_clk_en <= '0';
104 elsif( s_packet_counter > 0 ) then
105 s_bit_counter <= t_bit_counter'high;
106 s_pause_counter <= t_pause_counter'high;
107 s_packet_counter <= s_packet_counter - 1;
108 o_n_ce <= s_cs_out;
109 if( i_data_selector = '0' ) then
110 o_dout <= G_DATA1( s_bit_counter + s_packet_counter*G_NUM_BITS_PACKET - 1 + s_device_counter*C_DATALEN_PER_DEVICE ); -- here s_bit_counter = 0, s_packet_counter points to previous packet. Therefore -1 to get the msb of current packet.
111 else
112 o_dout <= G_DATA2( s_bit_counter + s_packet_counter*G_NUM_BITS_PACKET - 1 + s_device_counter*C_DATALEN_PER_DEVICE );
113 end if;
114 s_o_clk_en <= '1';
115 elsif( s_device_counter > 0 ) then
116 s_cs_out <= s_cs_out( s_cs_out'high-1 downto s_cs_out'low ) & '1';
117 s_device_counter <= s_device_counter - 1;
118  
119 -- follows pause.
120 s_bit_counter <= 0;
121 s_pause_counter <= t_pause_counter'high;
122 s_packet_counter <= t_packet_counter'high;
123 o_n_ce <= ( o_n_ce'range => '1' );
124 o_dout <= '0';
125 s_o_clk_en <= '0';
126  
127 end if;
128 end if;
129 end process;
130  
131  
132 end architecture;