- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
http://www.alteraforum.com/forum/attachment.php?attachmentid=10118&stc=1
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, correctIndication); -- 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 much appreciated. Kind regards, Deadman
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
1. you forgot to use the numeric_std library in your code (you're converting from integer to slv via an unsigned type). So put at the top
use ieee.numeric_std.all; 2. di_m abd wren_m are inputs , you cannot assign a value to input. (line 41, 54, 58). You can only assign values to outputs. 3. The count variable is useless. The first time you're in the delay state it's value will be 2, and you'll go strait to write_enable (learn how signals work vs variables0 4. You cannot read values from outputs (assuming you're trying to compile with VHDL 1993 code). I highly suggest you read the errors. They are usually very descriptive.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- 1. you forgot to use the numeric_std library in your code (you're converting from integer to slv via an unsigned type). So put at the top use ieee.numeric_std.all; 2. di_m abd wren_m are inputs , you cannot assign a value to input. (line 41, 54, 58). You can only assign values to outputs. 3. The count variable is useless. The first time you're in the delay state it's value will be 2, and you'll go strait to write_enable (learn how signals work vs variables0 4. You cannot read values from outputs (assuming you're trying to compile with VHDL 1993 code). I highly suggest you read the errors. They are usually very descriptive. --- Quote End --- Thank you for your reply. I have read the errors and corrected them, the code is compiling. Do you know how to generate random numbers to inputs and outputs instead if fixed values? Kind regards, Deadman
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Thank you for your reply. I have read the errors and corrected them, the code is compiling. Do you know how to generate random numbers to inputs and outputs instead if fixed values? Kind regards, Deadman --- Quote End --- There are two ways. 1. If you need synthesisable pseudo random number, then google linear feedback shift register (LFSR). 2. For simulation only, the ieee.math_real package has a procedure called "uniform" that generates pseudo random real values between 0.0 and 1.0. You can use these to scale any value you want. For example, a rand_int procedure in my personal testbench tools package:
procedure rand_int( variable seed1, seed2 : inout positive; min, max : in integer; result : out integer) is
variable rand : real;
variable val_range : real;
begin
assert (max >= min) report "Rand_int: Range Error" severity Failure;
uniform(seed1, seed2, rand);
val_range := real(Max - Min + 1);
result := integer( trunc(rand * val_range )) + min;
end procedure;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am still trying to write a state machine that checks to see if correct data is being received between the input 'di_i' and the output 'do_o' but I get the following error message:
Error (10409): VHDL Type Conversion error at spi_statemachine.vhd(89): converted type of object near text or symbol "std_logic_vector" must match integer type of target object
I have highlighted the error in red below. I do not know why I am getting this error message, I have set 'std_logic_vector' and 'data_out' to 16 bits. library IEEE; -- Reference for VHDL source code
use IEEE.STD_LOGIC_1164.all; -- Package defined in the IEEE (Found in library IEEE)
use IEEE.numeric_std.all; -- Used to covert integer to std_logic_vector via unsigned type.
-- Unsigned types represent postive values including zero. The compiler interprets each
-- unsigned type as a binary number, with the digit of the left as the MSB (Most Significant Bit)
-- Entity declaration
entity spi_statemachine is -- Entity name
-- Generics --
generic (n: positive := 16); -- Number of bits. Generic is used to specify parameters, for example, the
-- length of data.
port (-- Inputs --
di_i: in std_logic_vector(n-1 downto 0); -- Data in
do_valid_o: in std_logic; -- Check if data is valid (No data setup glitches on the data transfer),
-- valid during one clk_i rising edge
-- Outputs --
do_o: out std_logic_vector(n-1 downto 0); -- Data out
wren_i: out std_logic; -- Write port, valid during one clk_i rising edge
-- Start operation --
start: in std_logic; -- Start state machine
-- Clock operation --
rst_i: in std_logic;
clk_i: in std_logic; -- Clock synchronicity with data
-- Output indication --
correct: out std_logic); -- Check if data transmitted is correct
end spi_statemachine; -- End entity
-- Architecture behaviour
architecture detect of spi_statemachine is -- Identifying the architecture
type state_type is (createData, writeData, delay, writeEnable,
checkValid, compareData, checkFinished, correctData); -- Enumeration types
-- Signals
signal state: state_type; -- State of the machine
begin
P1: process (clk_i, rst_i, start) -- Sensitivity list. The process wakes up when an event occurs
-- on one of the signals in the sensitivity list.
-- Variables --
-- Variables change immediately therefore 'rst_i' is used to stop this from happening.
variable data: integer := 15; -- Data length. Integer is a data type that represents positive and negative
-- whole numbers.
variable error_rate: natural := 0; -- Incrementing error. Natural is a data type is used to represent natural
-- (nonnegative) numbers.
variable data_in: integer := 15;
variable data_out: integer := 15;
begin
if rst_i = '1' then -- Reset operation used initialize all signals to predetermined state
do_o <= (others => '0');
wren_i <= '0';
correct <= '0';
data := 15;
error_rate := 0;
state <= createData;
data_in := 15;
data_out := 15;
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 =>
if (start = '1') then -- Start state machine
state <= writeData;
else
state <= createData;
end if;
when writeData =>
data_out := std_logic_vector(to_unsigned(data, n)); -- Write data
state <= delay;
when delay =>
state <= writeEnable;
when writeEnable =>
wren_i <= '1';
state <= checkValid;
when checkValid =>
if (do_valid_o = '1') then
data_in := di_i;
wren_i <= '0';
state <= compareData;
else
state <= writeEnable;
end if;
when compareData =>
if data_in = data_out then
error_rate := error_rate-1;
else
error_rate := error_rate+1;
state <= checkFinished;
end if;
when checkFinished =>
if (error_rate > 0) then
correct <= '0';
else
correct <= '1';
end if;
end case;
end if;
end process;
end detect;
Kind regards, Deadman
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
data_out is an integer variable. So is the data variable. So no need to convert to std_logic_vector.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ps. data_out and data are always 15. What are you trying to do with these variables?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- ps. data_out and data are always 15. What are you trying to do with these variables? --- Quote End --- I am trying to assign them to input 'di_i' and the output 'do_o' so that I can compare them, please see the code highlighted in red below.
library IEEE; -- Reference for VHDL source code
use IEEE.STD_LOGIC_1164.all; -- Package defined in the IEEE (Found in library IEEE)
use IEEE.numeric_std.all; -- Used to covert integer to std_logic_vector via unsigned type.
-- Unsigned types represent postive values including zero. The compiler interprets each
-- unsigned type as a binary number, with the digit of the left as the MSB (Most Significant Bit)
-- Entity declaration
entity spi_statemachine is -- Entity name
-- Generics --
generic (n: positive := 16); -- Number of bits. Generic is used to specify parameters, for example, the
-- length of data.
port (-- Inputs --
di_i: in std_logic_vector(n-1 downto 0); -- Data in
do_valid_o: in std_logic; -- Check if data is valid (No data setup glitches on the data transfer),
-- valid during one clk_i rising edge
-- Outputs --
do_o: out std_logic_vector(n-1 downto 0); -- Data out
wren_i: out std_logic; -- Write port, valid during one clk_i rising edge
-- Start operation --
start: in std_logic; -- Start state machine
-- Clock operation --
rst_i: in std_logic;
clk_i: in std_logic; -- Clock synchronicity with data
-- Output indication --
correct: out std_logic); -- Check if data transmitted is correct
end spi_statemachine; -- End entity
-- Architecture behaviour
architecture detect of spi_statemachine is -- Identifying the architecture
type state_type is (createData, writeData, delay, writeEnable,
checkValid, compareData, checkFinished, correctData); -- Enumeration types
-- Signals
signal state: state_type; -- State of the machine
begin
P1: process (clk_i, rst_i, start) -- Sensitivity list. The process wakes up when an event occurs
-- on one of the signals in the sensitivity list.
-- Variables --
-- Variables change immediately therefore 'rst_i' is used to stop this from happening.
variable data: integer := 15; -- Data length. Integer is a data type that represents positive and negative
-- whole numbers.
variable error_rate: natural := 0; -- Incrementing error. Natural is a data type is used to represent natural
-- (nonnegative) numbers.
variable data_in: integer := 15;
variable data_out: integer := 15;
begin
if rst_i = '1' then -- Reset operation used initialize all signals to predetermined state
do_o <= (others => '0');
wren_i <= '0';
correct <= '0';
data := 15;
error_rate := 0;
state <= createData;
data_in := 15;
data_out := 15;
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 =>
if (start = '1') then -- Start state machine
state <= writeData;
else
state <= createData;
end if;
when writeData =>
data_out := std_logic_vector(to_unsigned(data, n)); -- Write data
state <= delay;
when delay =>
state <= writeEnable;
when writeEnable =>
wren_i <= '1';
state <= checkValid;
when checkValid =>
if (do_valid_o = '1') then
data_in := di_i;
wren_i <= '0';
state <= compareData;
else
state <= writeEnable;
end if;
when compareData =>
if data_in = data_out then
error_rate := error_rate-1;
else
error_rate := error_rate+1;
state <= checkFinished;
end if;
when checkFinished =>
if (error_rate > 0) then
correct <= '0';
else
correct <= '1';
end if;
end case;
end if;
end process;
end detect;
Kind regards, Deadman
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
di_i is a std_logic_vector, so to assign it to the data in variable you need to type convert it:
data_in <= to_integer( unsigned( di_i) ); And you still have the same problem that you're doing an unnecessary (and illegal) type conversion for the data_out assignment from the data variable. There are other type conversion problems. I suggest fix the syntax errors first before worry about the functionality.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have fixed the syntax errors and my state machine is compiling.
My state machine is the following code:library IEEE; -- Reference for VHDL source code
use IEEE.STD_LOGIC_1164.all; -- Package defined in the IEEE (Found in library IEEE)
use IEEE.numeric_std.all; -- Used to covert integer to std_logic_vector via unsigned type. Unsigned types represent postive
-- values including zero. The compiler interprets each unsigned type as a binary number, with the
-- digit of the left as the MSB (Most Significant Bit).
-- Entity declaration
entity spi_statemachine is -- Entity name.
-- Generics --
generic (n: positive := 16); -- Number of bits. Generic is used to specify parameters, for example, the length of data.
port (-- Inputs --
do_o: in std_logic_vector(n-1 downto 0); -- Data in.
do_valid_o: in std_logic; -- Check if data is valid (No data setup glitches on the data transfer), valid during one
-- clk_i rising edge.
-- Outputs --
di_i: out std_logic_vector(n-1 downto 0); -- Data out.
wren_i: out std_logic; -- Write port, valid during one clk_i rising edge.
-- Start operation --
start: in std_logic; -- Start state machine.
-- Clock operation --
rst_i: in std_logic;
clk_i: in std_logic; -- Clock synchronicity with data.
-- Output indication --
correct: out std_logic); -- Check if data transmitted is correct.
end spi_statemachine; -- End entity
-- Architecture behaviour
architecture detect of spi_statemachine is -- Identifying the architecture.
type state_type is (createData, writeData, delay, stopwriteEnable,
checkValid, compareData, checkFinished); -- Enumeration types.
-- Signals and types
signal state: state_type; -- State of the machine.
type int_array is array (integer range <>) of integer;
begin
P1: process (clk_i, rst_i, start) -- Sensitivity list. The process wakes up when an event occurs on one of the signals
-- in the sensitivity list.
-- Variables -- (Variables change immediately therefore 'rst_i' is used to stop this from happening)
variable error_rate: natural := 0; -- Incrementing error. Natural is a data type is used to represent natural
-- (nonnegative) numbers.
variable data_in: std_logic_vector(n-1 downto 0); -- Data length. Integer is a data type that represents positive and
-- negative whole numbers.
variable data_out: std_logic_vector(n-1 downto 0);
variable random_data: int_array(0 to 15);
variable count: integer := 0;
variable i: integer := 0;
begin
if rst_i = '1' then -- Reset operation used initialize all signals to predetermined state.
-- Initial values for all outputs, variables and signals --
di_i <= (others => '0');
wren_i <= '0';
correct <= '0';
error_rate := 0;
data_in := (others => '0');
data_out := (others => '0');
count := 0;
i := 0;
random_data(0) := 14492;
random_data(1) := 9335;
random_data(2) := 10648;
random_data(3) := 21153;
random_data(4) := 14657;
random_data(5) := 10583;
random_data(6) := 10651;
random_data(7) := 18398;
random_data(8) := 12598;
random_data(9) := 30086;
random_data(10) := 6444;
random_data(11) := 25436;
random_data(12) := 25025;
random_data(13) := 27533;
random_data(14) := 3525;
random_data(15) := 31968;
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 state 'createData' and if 'start' equals '1', then state is 'writeData' and 'i' increments count from
-- 0 to 15. If 'i' increments count above 15 then 'i' equals 0 and otherwise state is 'createData'.
when createData =>
if (start = '1') then
state <= writeData;
i := i + 1;
if (i > 15) then
i := 0;
end if;
else
state <= createData;
end if;
-- 'random_data' is converted into 'std_logic_vector' and is then is written in to 'data_out' and 'di_i'.
-- 'random_data' will be counted (i) up to 15 (n).
when writeData =>
data_out := std_logic_vector(to_unsigned(random_data(i), n));
di_i <= std_logic_vector(to_unsigned(random_data(i), n));
state <= delay;
when delay =>
count := count + 1;
if (count > 1) then
state <= stopwriteEnable;
wren_i <= '1'; -- Starts transmission.
count := 0;
else
state <= delay;
end if;
when stopwriteEnable =>
state <= checkValid;
-- If 'do_valid_o' equals '1' then 'do_o' gets the value of 'data_in'. 'wren_i' equals '0' as it only as
-- only equals '1' for one clock cycle.
when checkValid =>
if (do_valid_o = '1') then
data_in := do_o;
wren_i <= '0';
state <= compareData;
else
state <= checkValid;
end if;
-- If 'data_in' equals 'data_out' and the error rate is below '0' then there is no error, if the error
-- rate is above '0' then there is an error.
when compareData =>
if data_in = data_out then
error_rate := error_rate - 1;
else
error_rate := error_rate + 1;
end if;
state <= checkFinished;
-- If the error rate is greater than '0' then correct equals '0', otherwise correct equals '1'.
when checkFinished =>
if (error_rate > 0) then
correct <= '0';
else
correct <= '1';
end if;
end case;
end if;
end process;
end detect;
Kind regards, Deadman
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am trying to write a test bench for my state machine but I don't seem to be getting the correct results.
The test bench for my state machine is the following code:library IEEE;
use IEEE.STD_LOGIC_1164.all;
-- Entity --
entity spi_statemachine_test is
generic (n: positive := 16);
end spi_statemachine_test;
-- Component declaration --
architecture behaviour of spi_statemachine_test is
component spi_statemachine
port (do_o: in std_logic_vector(n-1 downto 0);
do_valid_o: in std_logic;
di_i: out std_logic_vector(n-1 downto 0);
wren_i: out std_logic;
start: in std_logic;
rst_i: in std_logic;
clk_i: in std_logic;
correct: out std_logic);
end component;
-- Signals --
signal clk_i: std_logic;
signal start: std_logic;
signal rst_i: std_logic;
signal wren_i: std_logic;
signal di_i: std_logic_vector(n-1 downto 0);
signal do_valid_o: std_logic;
signal do_o: std_logic_vector(n-1 downto 0);
signal correct: std_logic;
-- Clock period --
constant clk_period: time := 10 ns;
-- Compomemt instantiation --
begin
C: spi_statemachine
port map(di_i => di_i,
wren_i => wren_i,
do_o => do_o,
do_valid_o => do_valid_o,
start => start,
rst_i => rst_i,
clk_i => clk_i,
correct => correct);
-- Clock --
clk_process_slave: process
begin
clk_i <= '0';
wait for clk_period/2;
clk_i <= '1';
wait for clk_period/2;
end process clk_process_slave;
-- Stimulus --
stimulus: process is
variable data_v: std_logic_vector(n-1 downto 0);
begin
start <= '1';
rst_i <= '1';
do_valid_o <= '0';
do_o <= (others => '0');
wait for 15ns;
rst_i <= '0';
wait until wren_i'event and wren_i = '1';
data_v := di_i;
wait until clk_i'event and clk_i = '1';
do_o <= data_v;
wait until clk_i'event and clk_i = '1';
wait until clk_i'event and clk_i = '1';
do_valid_o <= '1';
wait until clk_i'event and clk_i = '1';
do_valid_o <= '0';
wait until clk_i'event and clk_i = '1';
assert correct <= '0'
report "There in an incorrect value on the output LED)"
severity error;
wait for 5ns;
wait;
end process stimulus;
end behaviour;
The following screenshot is of my simulation, 'correct' should be high because the correct data is being received between 'di_i' and 'do_o'. https://www.alteraforum.com/forum/attachment.php?attachmentid=10201 Kind regards, Deadman
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page