i2c communication using mpu6050 as slave in vhdl

Status
Not open for further replies.

DEVI403

Newbie level 5
Joined
Nov 10, 2014
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
244
Hellow everyone,

I am using spartan 3e and xilinx. The following is the code for i2c communiction using mpu 6050 as slave. I am trying to read who am i register. Resulting data through uart. Always I am getting FF only. Following is my code can anyone help me please???

//code

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
--------------------------------------------------------------------------------
--
--   FileName:         i2c_master.vhd
--   Dependencies:     none
--   Design Software:  Quartus II 32-bit Version 11.1 Build 173 SJ Full Version
--
--   HDL CODE IS PROVIDED "AS IS."  DIGI-KEY EXPRESSLY DISCLAIMS ANY
--   WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
--   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
--   PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY
--   BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
--   DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
--   PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
--   BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
--   ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
--
--   Version History
--   Version 1.0 11/1/2012 Scott Larson
--     Initial Public Release
--   Version 2.0 06/20/2014 Scott Larson
--     Added ability to interface with different slaves in the same transaction
--     Corrected ack_error bug where ack_error went 'Z' instead of '1' on error
--     Corrected timing of when ack_error signal clears
--    
--------------------------------------------------------------------------------
 
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
 
ENTITY i2c_master IS
    
  PORT(
    clk       :  IN      STD_LOGIC;                    --system clock
    reset_n   :  INOUT      STD_LOGIC := '0';                    --active low reset
    ena       :  IN      STD_LOGIC;                    --latch in command
    addr      :  INout      STD_LOGIC_VECTOR(6 DOWNTO 0); --address of target slave
     reg_addrr :  IN        STD_LOGIC_VECTOR(6 DOWNTO 0);
    rw        :  INout      STD_LOGIC;                    --'0' is write, '1' is read
    data_wr   :  IN      STD_LOGIC_VECTOR(7 DOWNTO 0); --data to write to slave
    busy      :  OUT     STD_LOGIC;                    --indicates transaction in progress
    data_rd   :  OUT     STD_LOGIC_VECTOR(7 DOWNTO 0); --data read from slave
    ack_error :  INOUT  STD_LOGIC;                    --flag if improper acknowledge from slave
    sda       :  INOUT   STD_LOGIC;                    --serial data output of i2c bus
     leds      :  OUT     STD_LOGIC_VECTOR(7 DOWNTO 0);
    scl       :  INOUT   STD_LOGIC);                   --serial clock output of i2c bus
END i2c_master;
 
ARCHITECTURE logic OF i2c_master IS
  CONSTANT input_clk :  INTEGER := 50_000_000; --input clock speed from user logic in Hz
  CONSTANT bus_clk   :  INTEGER := 400_000;   --speed the i2c bus (scl) will run at in Hz
  CONSTANT divider  :  INTEGER := (input_clk/bus_clk)/4; --number of clocks in 1/4 cycle of scl
  TYPE machine IS(ready, start, command, slv_reg_adrs, wr, rd, slv_ack2,slv_ack3,mstr_ack, stop); --needed states
  SIGNAL  state     :  machine := ready;                          --state machine
  SIGNAL  data_clk  :  STD_LOGIC;                        --clock edges for sda
  SIGNAL data_clk_prev : STD_LOGIC;                      --data clock during previous system clock
  SIGNAL  scl_clk   :  STD_LOGIC;                        --constantly running internal scl
  SIGNAL  scl_ena   :  STD_LOGIC := '0';                 --enables internal scl to output
  SIGNAL  sda_int   :  STD_LOGIC := '1';                 --internal sda
  SIGNAL  sda_ena_n :  STD_LOGIC;                        --enables internal sda to output
  SIGNAL  addr_rw   :  STD_LOGIC_VECTOR(7 DOWNTO 0);     --latched in address and read/write
  SIGNAL  reg_addr_rw:  STD_LOGIC_VECTOR(6 DOWNTO 0);
  SIGNAL  data_tx   :  STD_LOGIC_VECTOR(7 DOWNTO 0);     --latched in data to write to slave
  SIGNAL  data_rx   :  STD_LOGIC_VECTOR(7 DOWNTO 0);     --data received from slave
  SIGNAL  bit_cnt   :  INTEGER RANGE 0 TO 7 := 7;        --tracks bit number in transaction
  SIGNAL  stretch   :  STD_LOGIC := '0';                 --identifies if slave is stretching scl
  SIGNAL RD_FLAG    :  STD_LOGIC := '1';
  SIGNAL EN_RD_FLAG :  STD_LOGIC := '0';  
BEGIN
 
  --generate the timing for the bus clock (scl_clk) and the data clock (data_clk)
  PROCESS(clk, reset_n)
    VARIABLE count  :  INTEGER RANGE 0 TO divider*4;  --timing for clock generation
  BEGIN
    IF(reset_n = '0') THEN                --reset asserted
      stretch <= '0';
      count := 0;
    ELSIF(clk'EVENT AND clk = '1') THEN
       data_clk_prev <= data_clk; 
      IF(count = divider*4-1) THEN        --end of timing cycle
        count := 0;                       --reset timer
      ELSIF(stretch = '0') THEN           --clock stretching from slave not detected
        count := count + 1;               --continue clock generation timing
      END IF;
      CASE count IS
        WHEN 0 TO divider-1 =>            --first 1/4 cycle of clocking
          scl_clk <= '0';
          data_clk <= '0';
        WHEN divider TO divider*2-1 =>    --second 1/4 cycle of clocking
          scl_clk <= '0';
          data_clk <= '1';
        WHEN divider*2 TO divider*3-1 =>  --third 1/4 cycle of clocking
          scl_clk <= '1';                 --release scl
          IF(scl = '0') THEN              --detect if slave is stretching clock
            stretch <= '1';
          ELSE
            stretch <= '0';
          END IF;
          data_clk <= '1';
        WHEN OTHERS =>                    --last 1/4 cycle of clocking
          scl_clk <= '1';
          data_clk <= '0';
      END CASE;
    END IF;
  END PROCESS;
 
  --state machine and writing to sda during scl low (data_clk rising edge)
  PROCESS(clk, reset_n)
  BEGIN
    IF(reset_n = '0') THEN                 --reset asserted
      state <= ready;                      --return to initial state
      busy <= '0';                         --indicate not available
      scl_ena <= '0';                      --sets scl high impedance
      sda_int <= '1';                      --sets sda high impedance
      bit_cnt <= 7;                        --restarts data bit counter
      data_rd <= "00000000";               --clear data read port
        reset_n <= '1';
    ELSIF(clk'EVENT AND clk = '1') THEN
    IF(data_clk = '1' AND data_clk_prev = '0') THEN
      CASE state IS
        WHEN ready =>                      --idle state
          IF(ena = '1') THEN               --transaction requested
                 addr <= "1101000";
                  rw <= '0';
              busy <= '1';                   --flag busy
              addr_rw <= addr & rw;          --collect requested slave address and command
              data_tx <= data_wr;            --collect requested data to write
                  RD_FLAG <= '1';
                  EN_RD_FLAG <= '0';
              state <= start;                --go to start bit
            ELSE                             --remain idle
              busy <= '0';                   --unflag busy
              state <= ready;                --remain idle
            END IF;
        WHEN start =>                      --start bit of transaction
          IF EN_RD_FLAG = '1' THEN
                RD_FLAG <= '0';
                busy <= '1';
                sda_int <= addr_rw(bit_cnt);     --set first address bit to bus
            state <= command;
            ELSE
            busy <= '1';                     --resume busy if continuous mode
            sda_int <= addr_rw(bit_cnt);     --set first address bit to bus
            state <= command;                --go to command
            END IF;
        WHEN command =>                    --address and command byte of transaction
          IF(bit_cnt = 0) THEN             --command transmit finished
            sda_int <= '1';                --release sda for slave acknowledge
            bit_cnt <= 7;                  --reset bit counter for "byte" states
            state <= slv_reg_adrs;             --go to slave acknowledge (command)
          ELSE                             --next clock cycle of command state
            bit_cnt <= bit_cnt - 1;        --keep track of transaction bits
            sda_int <= addr_rw(bit_cnt-1); --write address/command bit to bus
            state <= command;              --continue with command
          END IF;
        WHEN slv_reg_adrs =>                   --slave acknowledge bit (command)
           IF EN_RD_FLAG = '1' THEN
               EN_RD_FLAG <= '0';
               sda_int <= '1';                --release sda from incoming data
            state <= rd;                   --go to read byte
           ELSIF(bit_cnt = 0) THEN             --command transmit finished
            sda_int <= '1';                --release sda for slave acknowledge
            bit_cnt <= 7;                  --reset bit counter for "byte" states
            state <= slv_ack2;             --go to slave acknowledge (command)
          ELSE                             --next clock cycle of command state
               bit_cnt <= bit_cnt - 1;        --keep track of transaction bits
               sda_int <= reg_addr_rw(bit_cnt-1); --write address/command bit to bus
            state <= slv_reg_adrs;               --continue with command
          END IF;
          WHEN slv_ack2 =>
            IF RD_FLAG = '1' THEN
               --addr <="1101000";
                --rw  <= '1';
                --addr_rw <= addr & rw;
                EN_RD_FLAG <= '1';
                addr_rw <= "11010001";
                state <= start;
          ELSIF(addr_rw(0) = '0') THEN        --write command
            sda_int <= data_tx(bit_cnt);   --write first bit of data
            state <= wr;                   --go to write byte
          ELSE                             --read command
            sda_int <= '1';                --release sda from incoming data
            state <= rd;                   --go to read byte
          END IF;
        WHEN wr =>                         --write byte of transaction
          busy <= '1';                     --resume busy if continuous mode
          IF(bit_cnt = 0) THEN             --write byte transmit finished
            sda_int <= '1';                --release sda for slave acknowledge
            bit_cnt <= 7;                  --reset bit counter for "byte" states
            state <= slv_ack3;             --go to slave acknowledge (write)
          ELSE                             --next clock cycle of write state
            bit_cnt <= bit_cnt - 1;        --keep track of transaction bits
            sda_int <= data_tx(bit_cnt-1); --write next bit to bus
            state <= wr;                   --continue writing
          END IF;
         WHEN rd =>                         --read byte of transaction
            busy <= '1';                     --resume busy if continuous mode
            IF(bit_cnt = 0) THEN             --read byte receive finished
              IF(ena = '1' AND addr_rw = addr & rw) THEN  --continuing with another read at same address
                sda_int <= '0';              --acknowledge the byte has been received
              ELSE                           --stopping or continuing with a write
                sda_int <= '1';              --send a no-acknowledge (before stop or repeated start)
              END IF;
              bit_cnt <= 7;                  --reset bit counter for "byte" states
                  leds <= data_rx;
              data_rd <= data_rx;            --output received data
              state <= mstr_ack;             --go to master acknowledge
            ELSE                             --next clock cycle of read state
              bit_cnt <= bit_cnt - 1;        --keep track of transaction bits
              state <= rd;                   --continue reading
            END IF;
          WHEN slv_ack3 =>                   --slave acknowledge bit (write)
            IF(ena = '1') THEN               --continue transaction
              busy <= '0';                   --continue is accepted
              addr_rw <= addr & rw;          --collect requested slave address and command
              data_tx <= data_wr;            --collect requested data to write
              IF(addr_rw = addr & rw) THEN   --continue transaction with another write
                sda_int <= data_wr(bit_cnt); --write first bit of data
                state <= wr;                 --go to write byte
              ELSE                           --continue transaction with a read or new slave
                state <= start;              --go to repeated start
              END IF;
            ELSE                             --complete transaction
              state <= stop;                 --go to stop bit
            END IF;
          WHEN mstr_ack =>                   --master acknowledge bit after a read
            IF(ena = '1') THEN               --continue transaction
              busy <= '0';                   --continue is accepted and data received is available on bus
              addr_rw <= addr & rw;          --collect requested slave address and command
              data_tx <= data_wr;            --collect requested data to write
              IF(addr_rw = addr & rw) THEN   --continue transaction with another read
                sda_int <= '1';              --release sda from incoming data
                state <= rd;                 --go to read byte
              ELSE                           --continue transaction with a write or new slave
                state <= start;              --repeated start
              END IF;    
            ELSE                             --complete transaction
              state <= stop;                 --go to stop bit
            END IF;
          WHEN stop =>                       --stop bit of transaction
            busy <= '0';                     --unflag busy
            state <= ready;                  --go to idle state
        END CASE;    
    ELSIF(data_clk = '0' AND data_clk_prev = '1') THEN
     CASE state IS
          WHEN start =>                  
            IF(scl_ena = '0') THEN                  --starting new transaction
              scl_ena <= '1';                       --enable scl output
              ack_error <= '0';                     --reset acknowledge error output
            END IF;
          WHEN rd =>                                --receiving slave data
            data_rx(bit_cnt) <= sda;                --receive current slave data bit
          WHEN slv_ack2 =>                          --receiving slave acknowledge (write)
            IF(sda /= '0' OR ack_error = '1') THEN  --no-acknowledge or previous no-acknowledge
              ack_error <= '1';                     --set error output if no-acknowledge
            END IF;
                 WHEN slv_ack3 =>                          --receiving slave acknowledge (write)
            IF(sda /= '0' OR ack_error = '1') THEN  --no-acknowledge or previous no-acknowledge
              ack_error <= '1';                     --set error output if no-acknowledge
            END IF;
          WHEN stop =>
            scl_ena <= '0';                         --disable scl
          WHEN OTHERS =>
            NULL;
        END CASE;
      END IF;
    END IF;
  END PROCESS;  
  --set sda output
  WITH state SELECT
    sda_ena_n <=   data_clk WHEN start,  --generate start condition
                   NOT data_clk WHEN stop,    --generate stop condition
                   sda_int WHEN OTHERS;       --set to internal sda signal    
      
  --set scl and sda outputs
  scl <= '0' WHEN (scl_ena = '1' AND scl_clk = '0') ELSE 'Z';
  sda <= '0' WHEN sda_ena_n = '0' ELSE 'Z';
  
END logic;

 
Last edited by a moderator:

As this code is written by a third party - I assume it works.
You should post the complete code of your control logic - the upper hierarchy that stimulates the inputs and reads the outputs of the "i2c_master" component.
 

Dear sir,
Thank you for your replay. This is not completely third party code. I have modified code according to write and read sequence of mpu6050.
The top level code is as follows

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    14:40:02 11/03/2014 
-- Design Name: 
-- Module Name:    main_i2c - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
 
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
 
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
 
entity main_i2c is
port(
     clk_50    : IN STD_LOGIC;          --system clock
     SDA       : INOUT  STD_LOGIC;     --serial data output of i2c bus
    SCL       : INOUT  STD_LOGIC;       --serial clock output of i2c bus
     LEDS      : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
     TXD          : OUT    std_logic);      -- RS232 transmitted serial data
                     
end main_i2c;
 
architecture Behavioral of main_i2c is
    signal reset           :  STD_LOGIC := '1';                    --active low reset
    signal enable          :  STD_LOGIC ;                    --latch in command
     signal RST                 : std_logic := '0';
    signal slave_addr      :  STD_LOGIC_VECTOR(6 DOWNTO 0); --address of target slave
     signal slave_reg_addr  :  STD_LOGIC_VECTOR(6 DOWNTO 0); --address of target slave
    signal rw              :  STD_LOGIC;                    --'0' is write, '1' is read
    signal data_to_write   :  STD_LOGIC_VECTOR(7 DOWNTO 0); --data to write to slave
     signal data_to_read    :  STD_LOGIC_VECTOR(7 DOWNTO 0); --data to write to slave
    signal busy            :  STD_LOGIC:='0';                    --indicates transaction in progress
    signal data_rd         :  STD_LOGIC_VECTOR(7 DOWNTO 0); --data read from slave
    signal ack_error       :  STD_LOGIC;                    --flag if improper acknowledge from slave
     
--signals related to uart tx
signal dbInSig  :   std_logic_vector(7 downto 0);
 
begin
 
master: entity work.i2c_master(logic)
          port map(clk_50,reset,enable,slave_addr,slave_reg_addr,rw,data_to_write,busy,data_to_read,ack_error,sda,LEDS,scl);
uart : entity work.uart_tx(Behavioral)
        port map(TXD,clk_50,dbInSig,RST);   
process (clk_50,busy)
begin
if clk_50'EVENT AND clk_50 = '1' THEN
IF busy = '0' THEN
enable <= '1';
--rw <= '0';
slave_addr <= "1101000";
slave_reg_addr <="1110101"; 
else
enable <= '0';
end if;
end if;
end process;
 
process (clk_50,data_to_read)
begin
if clk_50'EVENT AND clk_50 = '1' THEN
dbInSig <= data_to_read;
end if;
end process; 
end Behavioral;

 
Last edited by a moderator:

I am very new to vhdl. exactly I dont how to simulate. I can create simulate files but I dont know How to modify those files
 

uart_tx.vhd file working perfectly.
The following is the code for uart transmission



Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
--  Uncomment the following lines to use the declarations that are
--  provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;
entity uart_tx is
    Port ( 
        TXD     : out std_logic;            
        CLK     : in  std_logic;                                --Master Clock = 50MHz
        DBIN    : in  std_logic_vector (7 downto 0);    --Data Bus in
        RST : in  std_logic);   --Master Reset
end uart_tx;
 
architecture Behavioral of uart_tx is
------------------------------------------------------------------------
-- Component Declarations
------------------------------------------------------------------------
 
------------------------------------------------------------------------
--  Local Type Declarations
------------------------------------------------------------------------
 
    type tstate is (
        sttIdle,            --Idle state
        sttTransfer,    --Move data into shift register
        sttShift            --Shift out data
        );
------------------------------------------------------------------------
-- Signal Declarations
------------------------------------------------------------------------
    constant baudDivide : std_logic_vector(7 downto 0) := "10100011";   --Baud Rate dividor, set now for a rate of 9600.
                                                                                                --Found by dividing 50MHz by 9600 and 16.
    signal tfReg    :  std_logic_vector(7 downto 0);                                --Transfer holding register
    signal tfSReg  :  std_logic_vector(10 downto 0)     := "11111111111";   --Transfer shift register
    signal clkDiv   :  std_logic_vector(8 downto 0) := "000000000";     --used for rClk
    signal rClkDiv :  std_logic_vector(3 downto 0)  := "0000";              --used for tClk
 
    signal tfCtr    :  std_logic_vector(3 downto 0) := "0000";              --used to delay in transfer
    signal tClk :  std_logic;                                   --Transfering Clock
    signal rClk :  std_logic := '0';                            --Receiving Clock
    
    signal load :  std_logic := '0';
    signal shift    :  std_logic := '0';
    signal par  :  std_logic;
   signal tClkRST   :  std_logic := '0';
 
    signal sttCur  :  tstate := sttIdle;                    --Current state in the Transfer state machine
    signal sttNext :  tstate;                                   --Next state in the Transfer staet machine
    
------------------------------------------------------------------------
-- Module Implementation
------------------------------------------------------------------------
 
begin
    tfReg <= DBIN;
    par <=  not ( ((tfReg(0) xor tfReg(1)) xor (tfReg(2) xor tfReg(3))) xor ((tfReg(4) xor tfReg(5)) xor (tfReg(6) xor tfReg(7))) );
 
--Clock Dividing Functions--
 
    process (CLK, clkDiv)                               --set up clock divide for rClk
        begin
            if (Clk = '1' and Clk'event) then
                if (clkDiv = baudDivide) then
                    clkDiv <= "000000000";
                else
                    clkDiv <= clkDiv +1;
                end if;
            end if;
        end process;
 
    process (clkDiv, rClk, CLK)                     --Define rClk
    begin
        if CLK = '1' and CLK'Event then
            if clkDiv = baudDivide then
                rClk <= not rClk;
            else
                rClk <= rClk;
            end if;
        end if;
    end process;    
 
    process (rClk)                                       --set up clock divide for tClk
        begin
            if (rClk = '1' and rClk'event) then
                rClkDiv <= rClkDiv +1;
            end if;
        end process;
 
    tClk <= rClkDiv(3); 
    
    process (tClk, tClkRST)                             --set up a counter based on tClk
        begin
            if (tClk = '1' and tClk'event) then
                if tClkRST = '1' then
                    tfCtr <= "0000";
                else
                    tfCtr <= tfCtr +1;
                end if;
            end if;
        end process;
 
    
 
    --This process loads and shifts out the transfer shift register--
    process (load, shift, tClk, tfSReg)
        begin
            TXD <= tfsReg(0);
            if tClk = '1' and tClk'Event then
                if load = '1' then
                    tfSReg (10 downto 0) <= ('1' & par & tfReg(7 downto 0) &'0');
                end if;
                if shift = '1' then
                                  
                    tfSReg (10 downto 0) <= ('1' & tfSReg(10 downto 1));
                end if;
            end if;
        end process;
 
    --  Transfer State Machine--
    process (tClk, RST)
        begin
            if (tClk = '1' and tClk'Event) then
                if RST = '1' then
                    sttCur <= sttIdle;
                else
                    sttCur <= sttNext;
                end if;
            end if;
        end process;
        
    --  This process generates the sequence of steps needed transfer the data--
    process (sttCur, tfCtr, tfReg, tclk)
        begin          
 
            case sttCur is
            
                when sttIdle =>
                    tClkRST <= '0';
                    shift <= '0';
                    load <= '0';
                    sttNext <= sttTransfer;
                    
                    
 
                when sttTransfer => 
                    shift <= '0';
                    load <= '1';
                    tClkRST <= '1';     
                    sttNext <= sttShift;
                    
 
                when sttShift =>
                    shift <= '1';
                    load <= '0';
                    tClkRST <= '0';
                    if tfCtr = "1100" then
                        sttNext <= sttIdle;
                    else
                        sttNext <= sttShift;
                    end if;
            end case;
        end process;                            
            
end Behavioral;

 
Last edited by a moderator:

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…