Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

spi slave code 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
Activity points
244
Hellow Everyone,

could any one post me spi slave code in vhdl by using cpol and cpha?
I have written one code but my slave code is able to receive data from master but the miso doesn't have any data.
The slave receiving data also not perfect some times some random data is receiving like with bit shifting.
Following is my slave 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
--
--   FileName:         spi_slave.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 7/5/2012 Scott Larson
--     Initial Public Release
--
--------------------------------------------------------------------------------
 
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
 
ENTITY spi_slave IS
  PORT(
    sclk         : IN     STD_LOGIC;  --spi clk from master
    ss_n         : IN     STD_LOGIC;  --active low slave select
    mosi         : IN     STD_LOGIC;  --master out, slave in
    rx_req       : IN     STD_LOGIC;  --'1' while busy = '0' moves data to the rx_data output
    tx_load_en   : IN     STD_LOGIC;  --asynchronous transmit buffer load enable
    tx_load_data : IN     STD_LOGIC_VECTOR(7 DOWNTO 0);  --asynchronous tx data to load
    rx_data      : OUT    STD_LOGIC_VECTOR(7 DOWNTO 0);  --receive register output to logic
    busy         : OUT    STD_LOGIC;  --busy signal to logic ('1' during transaction)
     wr_add       : IN STD_LOGIC;  --address of register to write ('0' = receive, '1' = status)
    rd_add        : IN STD_LOGIC;  --address of register to read ('0' = transmit, '1' = status)
     
    miso         : OUT    STD_LOGIC); --master in, slave out
END spi_slave;
 
ARCHITECTURE logic OF spi_slave IS
  constant cpol    : STD_LOGIC := '1';   --spi clock polarity mode
  constant cpha    : STD_LOGIC := '1';   --spi clock phase mode
  constant d_width : INTEGER := 8;      --data width in bits
  SIGNAL clk_toggles : INTEGER RANGE 0 TO d_width*2 + 1;     --count spi clock toggles
  SIGNAL toggle : INTEGER RANGE 0 TO d_width-1 := 0; --count spi clock toggles
  SIGNAL mode    : STD_LOGIC;  --groups modes by clock polarity relation to data
  SIGNAL clk     : STD_LOGIC;  --clock
  SIGNAL rx_buf  : STD_LOGIC_VECTOR(d_width-1 DOWNTO 0) := (OTHERS => '0');  --receiver buffer
  SIGNAL tx_buf  : STD_LOGIC_VECTOR(d_width-1 DOWNTO 0) := (OTHERS => '0');  --transmit buffer
BEGIN
  busy <= NOT ss_n;  --high during transactions
 
  --adjust clock so writes are on rising edge and reads on falling edge
  mode <= cpol XOR cpha;  --'1' for modes that write on rising edge
  WITH mode SELECT
    clk <= sclk WHEN '1',
           NOT sclk WHEN OTHERS;
              
  PROCESS(ss_n, clk, tx_load_en, rx_req,rd_add,wr_add)
  BEGIN
  --receive registers
  --write to the receive register from master
 IF (ss_n = '0') THEN
    IF(clk_toggles = d_width*2) THEN
        clk_toggles <= 0;               --reset spi clock toggles counter
        tx_buf <= tx_load_data;
        rx_data <= rx_buf;
    ELSE
        clk_toggles <= clk_toggles + 1; --increment spi clock toggles counter
    END IF;
                    
 IF((cpol = '0' AND cpha = '1') or (cpol = '1' AND cpha = '0')) then
 IF falling_edge(clk) and wr_add = '0' THEN
    rx_buf <=  rx_buf(d_width-2 DOWNTO 0) & mosi;
   END IF;
  IF rising_edge(clk) and rd_add = '0'  THEN
  miso <= tx_buf(d_width-1); --transmit data to master
        tx_buf(d_width-1 DOWNTO 0) <= tx_buf(d_width-2 DOWNTO 0)& tx_buf(d_width-1);  --shift through tx data
   END IF;
    
ELSIF((cpol = '0' AND cpha = '0') or (cpol = '1' AND cpha = '1')) then
IF rising_edge(clk) and wr_add = '0' THEN
    rx_buf <=  rx_buf(d_width-2 DOWNTO 0) & mosi;
   END IF;
  IF falling_edge(clk) and rd_add = '0'  THEN
  miso <= tx_buf(d_width-1); --transmit data to master
        tx_buf(d_width-1 DOWNTO 0) <= tx_buf(d_width-2 DOWNTO 0)& tx_buf(d_width-1);  --shift through tx data
   END IF;
  END IF;
 END IF;     
  END PROCESS;
END logic;



the main code is
----------------------------------------------------------------------------------

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
-- Company: 
-- Engineer: 
-- 
-- Create Date:    17:30:54 10/30/2014 
-- Design Name: 
-- Module Name:    main - 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;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.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 is
PORT(
     clk          : IN     STD_LOGIC;    --50 MHZ Board clock
    sclk         : IN     STD_LOGIC;  --spi clk from master
    ss_n         : IN     STD_LOGIC;  --active low slave select
    mosi         : IN     STD_LOGIC;  --master out, slave in
    miso         : OUT    STD_LOGIC;
     RST             : in std_logic := '0');
     
end main;



architecture Behavioral of main is



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
--signals related to slave
signal rx_req        : STD_LOGIC;
signal tx_load_en      : STD_LOGIC;
signal tx_load_data : STD_LOGIC_VECTOR(7 DOWNTO 0);
signal rx_data          : STD_LOGIC_VECTOR(7 DOWNTO 0);
signal busy             : STD_LOGIC:='0';
signal wr_add           : STD_LOGIC;
signal rd_add           : STD_LOGIC;
 
begin
   
   slave: entity work.spi_slave(logic)
            port map(sclk,ss_n,mosi,rx_req,tx_load_en,tx_load_data,rx_data,busy,wr_add,rd_add,miso);
PROCESS(clk,ss_n)
begin
if clk'event and clk = '1' then
if (ss_n = '0') then
wr_add <= '0';
rd_add <= '0';
else
wr_add <= '1';
rd_add <= '1';
tx_load_en <= '1';              -- to send data to master
tx_load_data <= "11010110"; --data to send to master    
rx_req <= '1';                      --To get received data from master
end if;
                    
end if;
end PROCESS;
 
 
end Behavioral;

 
Last edited by a moderator:

BradtheRad you cut the architecture from the entity code architecture Behavioral of main is is part of the code. :roll:

OP you should post the testbench code so someone can run it and see what is wrong with what you are doing. What you currently have doesn't help fix your problem as there isn't anything that I see that is wrong. Currently it looks like you didn't write either piece of code and are primarily having a problem using them.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top