EmbDev.net

Forum: FPGA, VHDL & Verilog State Machine for SPI Master/Slave Interface


Author: Nayan Patel (nay)
Posted on:
Attached files:

Rate this post
0 useful
not useful
Dear all,

I am trying to write a state machine that checks to see if correct data 
is being received on the SPI link by lighting an LED.

I have written a code but I am not sure if I am writing the state 
machine correctly, it definitely does not compile.

Here is the code that I have written in relation to the test bench, 
please find the file attached.

library IEEE; -- Reference for VHDL source code  
use IEEE.STD_LOGIC_1164.all; -- Package defined in the IEEE (Found in library IEEE)

-- Entity declaration
entity spi_statemachine is
   generic (n: positive := 16; -- Number of bits
  port (-- Master --                        
      di_m: in std_logic_vector(15 downto 0);
      wren_m: in std_logic;
      -- Slave --
      do_s: out std_logic_vector(15 downto 0);
      do_valid_s: out std_logic;
      -- Clock operation --
      rst_i: in std_logic;
      clk_i: in std_logic;
      -- Output detection --
      correct: out std_logic);
end spi_statemachine;

-- Architecture behaviour
architecture detect of spi_statemachine is
type state_type is (createData, writeData, delay, writeEnable,
              checkValid, receivedData, checkFinished);  -- Enumeration type
signal state: state_type;
begin
  P1: process (clk_i, rst_i) -- Clock and reset
  variable dataLength: integer := n; -- Length of data
  variable count: integer := 1;
  begin
    if rst_i = '0' then -- Reset operation used initialize all signals to predetermined state
      state <= createData; 
    elsif clk_i'event and clk_i = '1' then  -- Signal attribute used to test for a change on a signal
      case state is
        when createData =>
            state <= writeData;
          else
            state <= createData;
          end if;

        when writeData =>
            di_m <= std_logic_vector(to_unsigned(dataLength,n)); -- Write data
            state <= delay;
          
        when delay =>
            count := count + 1;
          if (count > 1) then
            state <= writeEnable;
          count := 0;
          else
            state <= delay;
          end if;
        
        when writeEnable =>
          wren_m <= '1';
          state <= checkValid;
          
        when checkValid =>
          wren_m <= '0';
          state <= receivedData;
        
        when receivedData =>
          if do_s = di_m then
            state <= checkFinished;
          end if;
        
        when checkFinished =>
          correct <= '1';
        when others => null;
      end case;
    end if;
  end process;
end detect;

Any kind of help will be appreciated.

Kind regards,

Nay

Author: ruusel (Guest)
Posted on:

Rate this post
0 useful
not useful
Hi nayan,
you have a lot of mistakes in your syntax. Check your brackets and be 
sure that every if has its else end endif aso...

Author: Nayan Patel (nay)
Posted on:

Rate this post
0 useful
not useful
ruusel wrote:
> Hi nayan,
> you have a lot of mistakes in your syntax. Check your brackets and be
> sure that every if has its else end endif aso...

Thank you for the reply.

How do I declare an output from the slave component to the code that I 
am writing above?

Kind regards,

Nayan

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Nayan Patel wrote:
> How do I declare an output from the slave component to the code that I
> am writing above?
What slave?

> it definitely does not compile.
But you get no warnings or error messages?

> Here is the code that I have written in relation to the test bench
So the waveform picture is what your code should do after being 
completed? Where's the testbench for that waveform?

Author: Nayan Patel (nay)
Posted on:
Attached files:

Rate this post
0 useful
not useful
Lothar Miller wrote:
> Nayan Patel wrote:
>> How do I declare an output from the slave component to the code that I
>> am writing above?
> What slave?
>
>> it definitely does not compile.
> But you get no warnings or error messages?
>
>> Here is the code that I have written in relation to the test bench
> So the waveform picture is what your code should do after being
> completed? Where's the testbench for that waveform?

I am using a master block to send data to the slave block and the state 
machine block will check to see if the correct data is received.

I get the following error message:
Error (10482): VHDL error at spi_statemachine.vhd(70): object "do_o" is used but not declared

I am trying to assign the output 'do_o' of the slave block to the input 
'di_m' of my state machine block.

Please find the file of the test bench attached.

Kind regards,

Nayan

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Nayan Patel wrote:
> Please find the file of the test bench attached.
This here could be cut down several lines:
-- Clock generator (50% duty cycle)
  -- Master clock --
  -- Serial clock --
  clk_process_serial: process        -- Identifying the process
  begin                        -- Begin process
       sclk_i <= '0';              -- Serial clock signal is '0'.
       wait for clk_period/2;          -- Serial clock signal is '0' for 5ns
       sclk_i <= '1';              -- Serial click signal is '1'
       wait for clk_period/2;          -- Serial clock signal is '1' after 10ns
  end process clk_process_serial;      -- End process
  
  -- Parallel clock --
  clk_process_parallel: process        -- Identifying the process
  begin                        -- Begin process
       pclk_i <= '0';              -- Slave clock signal is '0'.
       wait for clk_period/2;          -- Slave clock signal is '0' for 5ns
       pclk_i <= '1';              -- Slave clock signal is '1'
       wait for clk_period/2;          -- Slave clock signal is '1' after 10ns
  end process clk_process_parallel;    -- End process
  
  -- Slave clock --
    clk_process_slave: process        -- Identifying the process
  begin                        -- Begin process
       clk_i <= '0';                -- Slave clock signal is '0'.
       wait for clk_period/2;          -- Slave clock signal is '0' for 5ns
       clk_i <= '1';                -- Slave clock signal is '1'
       wait for clk_period/2;          -- Slave clock signal is '1' after 10ns
  end process clk_process_slave;      -- End process
Just by this here:
-- Clock generator (50% duty cycle)
  clk_i  <= not clk_i after clk_period/2; 
  sclk_i <= clk_i;
  pclk_i <= clk_i;

Nayan Patel wrote:
> I get the following error message:
I cannot find do_o in any of the VHDL code you provided. Is it hidden 
somewhere else?

And of course, this here won't work at all:
      :
      do_s: out std_logic_vector(15 downto 0);
      :
      :
          if do_s = di_m then    -- it is not allowed to read an output port!
      :
In VHDL a output cannot be read.

Author: Nayan Patel (nay)
Posted on:
Attached files:

Rate this post
0 useful
not useful
Lothar Miller wrote:
> Nayan Patel wrote:
>> I get the following error message:
> I cannot find do_o in any of the VHDL code you provided. Is it hidden
> somewhere else?

The output 'do_o' is read from the slave block, please find the file of 
the master block and slave block attached.

Kind regards,

Nayan

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
And where is the file with the line of code causing the errror:
spi_statemachine.vhd(70)

Heck, it is so exhausting to worm every small bit of information out of 
someone...  :-/

Author: Nayan Patel (nay)
Posted on:
Attached files:

Rate this post
0 useful
not useful
Lothar Miller wrote:
> And where is the file with the line of code causing the errror:
> spi_statemachine.vhd(70)
>
> Heck, it is so exhausting to worm every small bit of information out of
> someone...  :-/

Apologies for the confusion, please find state machine file attached.

I have also attached the wrapper (Top-level entity) for the 'spi_master' 
and 'spi_slave' cores, to synthesize the 2 cores and test them in the 
simulator.

Kind regards,

Nayan

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.