How to setup adv7513? - vhdl

I'm setting up adv7513 on altera GX starter kit. Data that I've read from registers after setup is different from what I've sent.
I've tried to divide writes in to the single registers instead of one long transaction, and change the order of writes and reads, but I always read 0x03 from 0x98 and 0x00 from the rest of the registers.
I've used this i2c controller: https://www.digikey.com/eewiki/pages/viewpage.action?pageId=10125324
and I've made state machine in vhdl to control it, and write data stored in rom
if rising_edge(clk) then
case state is
when idle =>
if (beg='1') then
state <= start;
else
state <= idle;
end if;
when start =>
rom_addr <= count;
state <= lut_addr_i2c;
when lut_addr_i2c =>
ena <= '1';
rw <= '0';
addr <= "0111001";
data_wr <= lut_data(15 downto 8);
state <= lut_data_i2c;
when lut_data_i2c =>
if (busy='1' and busy_prev='0') then
data_wr <= lut_data(7 downto 0);
state <= cleanup;
count <= count+1;
end if;
when cleanup =>
if (busy='1' and busy_prev='0') then
state <= next_lut;
end if;
when next_lut =>
if (count = 31) then
state <= rd;
ena <= '0';
else
state <= start;
end if;
when rd =>
ready <= '1';
count <= 0;
if (rd_delay = 10000) then
state <= start_rd;
else
rd_delay <= rd_delay+1;
state <= rd;
end if;
when start_rd =>
rom_addr <= count;
if (next_rd = 20000) then
state <= rd_lut_addr;
next_rd <= 0;
else
next_rd <= next_rd+1;
state <= start_rd;
end if;
when rd_lut_addr =>
ena <= '1';
rw <= '0';
addr <= "0111001";
data_wr <= lut_data(15 downto 8);
state <= rd_lut;
when rd_lut =>
if (busy='1' and busy_prev='0') then
rw <= '1';
count <= count+1;
state <= rd_cleanup;
end if;
when rd_cleanup =>
if (busy='1' and busy_prev='0') then
state <= rd_next_lut;
end if;
when rd_next_lut =>
if (count = 31) then
state <= fin;
ena <= '0';
else
state <= start_rd;
ena <= '0';
end if;
when fin =>
state <= fin;
end case;
end if;
signal tap, what I write
signal tap, what I read

I think your problem is that you simply overrun the i2c slave. You should wait for not busy in your cleanup state latest after you've provided your second data byte.
Your code does not appear to wait for not busy at all?

Related

Testbench for FSM

I'm trying to implement a testbench for the following fsm in created in vhdl. The problem is that currently, I'm not seeing any state transitions in the test bench. The simulation stays at state 0.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity FPGA_Challenge is
Port ( led : out STD_LOGIC;
clk_in : in STD_LOGIC; -- 100 MHZ internal clock
reset : in STD_LOGIC; -- is reset necessary
button : in STD_LOGIC;
data_line : in STD_LOGIC);
end FPGA_Challenge;
architecture Behavioral of FPGA_Challenge is
type state_type is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20);
signal state: state_type;
signal x:std_logic;
signal y:std_logic;
signal count : integer:= 0;
--signal tmp: std_logic:= '1';
begin
process(clk_in, reset)
begin
if rising_edge(clk_in)then
if reset = '1'then -- Goes back to known state (state 0)
state <= s0;
count <= 0;
else
count <= count + 1;
case state is
-- Initial state- if button is pressed, then LED is lit and machine goes to state 2, if not it stays in state 1
when s0 =>
if (button <= '1') then
led <= '1';
state <= s1;
else
state <= s0;
led <= '0'; --is this necessary?
end if;
-- Beginning of preamble detection(states 1-17)
-- Count = ((freq in) / (freq out))/ 2 -1 = (100 MHz/ 2 MHz)/ 2 -1 = 50/2 - 1 (due to 50% duty cycle)
when s1=> -- do I need to put led = '1' in each state because it stays on ?
if (count = 25 -1) then
count <= 0;
if (data_line = '1')then
y <= '0';
-- led = '1';
state <= s2;
else
-- led = '1';
y <= '0';
state <= s1;
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s2 =>
if (count = 25-1) then
count <= 0;
if (data_line = '0')then
y <= '0';
-- led = '1';
state <= s3;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s3 =>
if (count = 25-1)then
count <= 0; ----reinitializes count
if (data_line <= '1')then
y <= '0';
-- led = '1';
state <= s4;
else
state <= s1;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s4 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s5;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s5 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s6;
else
state <= s4;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s6 =>
if (count= 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s7;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s7 =>
if (count = 25-1)then
count<= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s7;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s8 =>
if (count = 25-1)then
count <= 0;
if (data_line <='1')then
y <= '0';
-- led = '1';
state <= s9;
else
state <= s1;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s9 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
-- led = '1';
state <= s10;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s10=>
if (count = 25-1)then
count <= 0;
if (data_line <='1')then
y <= '0';
--led = '1';
state <= s11;
else
state <= s1;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s11 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s12;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s12 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s13;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s13 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
-- led = '1';
state <= s14;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s14 =>
if (count = 25-1)then
count <=0;
if (data_line <='0')then
y <= '0';
-- led = '1';
state <= s15;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s15 =>
if (count = 25-1)then
count <=0;
if (data_line <='0') then
y <= '0';
-- led = '1';
state <= s16;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s16 =>
if (count = 25-1) then
count <= 0;
if (data_line <='0')then
y <= '0';
-- led = '1';
state <= s17;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s17 =>
if (count = 25-1)then
count <= 0;
if (data_line ='1')then
y <= '1';
-- led = '1';
state <= s18;
else
state <= s1;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s18 => -- no real condition here except varying period of clock
if (count = 25)then
count <= 0; ----reinitializes count
state <= s19;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s19=> -- no real condition here except varying period of clock
if (count = 25)then
count <= 0; ----reinitializes count
state <= s0;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when others=>
null;
end case;
end if;
end if;
end process;
end architecture;
The following is the testbench I have so far. I have internal signals such as y(output for each state), and count(counter for how long I'm in a state) that I probably should be using as drivers in the testbench. Any input is appreciated
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity FPGA_tb is
-- Port ( );
end FPGA_tb;
architecture Behavioral of FPGA_tb is
component FPGA_Challenge is
Port( led : out STD_LOGIC;
clk_in : in STD_LOGIC; -- 100 MHZ internal clock
reset : in STD_LOGIC; -- is reset necessary
button : in STD_LOGIC;
data_line : in STD_LOGIC);
end component;
signal led : STD_LOGIC;
signal clk_in : STD_LOGIC; -- 100 MHZ internal clock
signal reset : STD_LOGIC; -- is reset necessary
signal button : STD_LOGIC;
signal data_line : STD_LOGIC;
type state_type is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20);
signal state: state_type;
signal x,y: std_logic;
signal count : integer:= 0;
begin
UUT: FPGA_Challenge
PORT MAP(
led => led,
clk_in => clk_in,
reset => reset,
button => button,
data_line => data_line
);
Testing: Process
begin
--wait until rising_edge(clk_in);
--wait until rising_edge(clk_in);
clk_in <='0';
reset <= '1';
button <= '0';
data_line <= '0';
WAIT For 10ns;
clk_in <='1';
reset <= '0';
button <= '1';
data_line <= '0';
WAIT For 10ns;
clk_in <='1';
reset <= '1';
button <= '0';
data_line <= '1';
WAIT For 10ns;
clk_in <='0';
reset <= '1';
button <= '0';
data_line <= '0';
WAIT For 10ns;
clk_in <='1';
reset <= '1';
button <= '0';
data_line <= '0';
WAIT For 10ns;
end process;
end Behavioral;
Try this in the testbench to have a running clock and proper reset
signal clk_in : STD_LOGIC := '1'; -- 100 MHZ internal clock
signal reset : STD_LOGIC := '1'; -- is reset necessary
clk_in <=NOT clk_in after 10ns;
reset <= 0 after 30ns;
play with button after the reset. that is, from 40ns

Warning (10631): VHDL Process Statement warning: inferring latch(es) for signal or variable

I'm trying learning to code in VHDL and the below code gives me no errors when compiling but gives me a latching warning. I need to get rid of this latch as I believe it is causing me problems in my next piece of code which will use this (8x8 multiplier).
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
ENTITY control IS
PORT (
clk, reset_a, start : IN STD_LOGIC;
count : IN UNSIGNED (1 DOWNTO 0);
input_sel, shift_sel : OUT UNSIGNED(1 DOWNTO 0);
state_out : OUT UNSIGNED(2 DOWNTO 0);
done, clk_ena, sclr_n : OUT STD_LOGIC
);
END ENTITY control;
ARCHITECTURE logic OF control IS
type logic_state is (idle, lsb, mid, msb, calc_done, err);
signal current_state: logic_state;
signal next_state: logic_state;
BEGIN
PROCESS (clk, reset_a)
BEGIN
if reset_a = '1' then
current_state <= idle;
elsif rising_edge (clk) then
current_state <= next_state;
end if;
END PROCESS;
PROCESS (current_state, start, count)
BEGIN
CASE current_state IS
when idle =>
if start = '1' then
next_state <= lsb;
else
next_state <= idle;
end if;
when lsb =>
if start = '0' and count = "00" then
next_state <= mid;
else
next_state <= err;
end if;
when mid =>
if start = '0' then
if (count = "01") then
next_state <= mid;
elsif (count = "10") then
next_state <= msb;
else
next_state <= err;
end if;
end if;
when msb =>
if start = '0' then
if (count = "11") then
next_state <= calc_done;
else
next_state <= err;
end if;
end if;
when calc_done =>
if start = '0' then
next_state <= idle;
else
next_state <= err;
end if;
when err =>
if start = '1' then
next_state <= lsb;
else
next_state <= err;
end if;
END CASE;
END PROCESS;
mealy: PROCESS (current_state, start, count)
BEGIN
input_sel <= "00";
shift_sel <= "00";
done <= '0';
clk_ena <= '0';
sclr_n <= '1';
CASE current_state IS
when idle =>
if start = '1' then
sclr_n <= '0';
clk_ena <= '1';
END IF;
when lsb =>
if start = '0' and count = "00" then
sclr_n <= '1';
end if;
when mid =>
if start = '0' then
if (count = "01") then
input_sel <= "01";
shift_sel <= "01";
elsif (count = "10") then
input_sel <= "10";
shift_sel <= "01";
end if;
end if;
when msb =>
if start = '0' then
if (count = "11") then
input_sel <= "11";
shift_sel <= "10";
end if;
end if;
when calc_done =>
if start = '0' then
input_sel <= "00";
shift_sel <= "00";
done <= '1';
clk_ena <= '0';
end if;
when err =>
if start = '1' then
input_sel <= "00";
shift_sel <= "00";
done <= '0';
clk_ena <= '1';
sclr_n <= '0';
end if;
END CASE;
END PROCESS mealy;
moore: PROCESS(current_state)
BEGIN
state_out <= "000";
CASE current_state IS
WHEN idle =>
WHEN lsb =>
state_out <= "001";
WHEN mid =>
state_out <= "010";
WHEN msb =>
state_out <= "011";
WHEN calc_done =>
state_out <= "100";
WHEN err =>
state_out <= "101";
END CASE;
END PROCESS moore;
END ARCHITECTURE logic;
I get the following warning:
Warning (10631): VHDL Process Statement warning at mult_control.vhd(65): inferring latch(es) for signal
or variable "next_state", which holds its previous value in one or more paths through the process
That points to this node (line 33):
PROCESS (current_state, start, count)
And that warning leads to other warnings (for every type .idle, .mid, .msb, etc.):
Warning (13012): Latch next_state.idle_218 has unsafe behavior
Warning (13013): Ports D and ENA on the latch are fed by the same signal start
Thank you!
line 33 is in the second process (with no label).
Why are there inferred latches?
See IEEE Std 1076.6-2004 (withdrawn) RTL Synthesis
6.2.1.1 Level-sensitive storage from process with sensitivity list
A level-sensitive storage element shall be modeled for a signal (or variable) when all the following apply:
a) The signal (or variable) has an explicit assignment.
b) The signal (or variable) does not have an execution path with as a condition.
c) There are executions of the process that do not execute an explicit assignment (via an assignment statement) to the signal (or variable).
By default, the effect of an identity assignment of the signal (or variable) shall be as though the assignment was not present.
If the combinational attribute decorates the signal (or variable), combinational logic with feedback shall be synthesized.
To avoid unintentional latches as condition c) has to be invalid.
An example in the question code that can cause latches:
when msb =>
if start = '0' then
if (count = "11") then
next_state <= calc_done;
else
next_state <= err;
end if;
end if;
This is missing an else for the outer if statement and meets rule c) quoted above. That can be cured:
when msb =>
if start = '0' then
if (count = "11") then
next_state <= calc_done;
else
next_state <= err;
end if;
else -- now all binary values of start in state msb assign next_state
next_state <= msb;
end if;
You can assign a value to a target before an if statement that otherwise meets c):
when msb =>
next_state <= msb; -- not always assigned in the if statement
if start = '0' then
if (count = "11") then
next_state <= calc_done;
else
next_state <= err;
end if;
end if;
In a sequence of statements the 'default' assignment occurs unless overwritten by a subsequent assignment in the if statement.
The question's code has other occurrences of c) issues (including in other processes) that can be similarly treated.

Finite State Machine with Its States Controlled by Two Processes

I'm trying to code a finite state machine (FSM) with VHDL language right now (and I'm actually new to VHDL). What I'm trying to achieve is, whenever the machine is in S11, the STint will decrease respectively with the CLK2 (So I can control how fast the decreasement is). However, S0 until S10 are controlled by CLK1.
Here is my code:
begin
process(state,DI,HI,QI,rst)
begin
case State is
when S0 =>
DO <= '0'; HO <= '0'; QO <= '0'; ST <= '0'; STint <= 9;
if DI'EVENT and DI = '1' then Nextstate <= S4;
elsif HI'EVENT and HI = '1' then Nextstate <= S2;
elsif QI'EVENT and QI = '1' then Nextstate <= S1;
elsif rst'EVENT and rst = '1' then Nextstate <= S10;
else Nextstate <= S0; end if;
when S1 =>
DO <= '0'; HO <= '0'; QO <= '0'; ST <= '0';
if DI'EVENT and DI = '1' then Nextstate <= S5;
elsif HI'EVENT and HI = '1' then Nextstate <= S3;
elsif QI'EVENT and QI = '1' then Nextstate <= S2;
elsif rst'EVENT and rst = '1' then Nextstate <= S10;
else Nextstate <= S1; end if;
when S2 =>
DO <= '0'; HO <= '0'; QO <= '0'; ST <= '0';
if DI'EVENT and DI = '1' then Nextstate <= S6;
elsif HI'EVENT and HI = '1' then Nextstate <= S4;
elsif QI'EVENT and QI = '1' then Nextstate <= S3;
elsif rst'EVENT and rst = '1' then Nextstate <= S10;
else Nextstate <= S2; end if;
when S3 =>
DO <= '0'; HO <= '0'; QO <= '0'; ST <= '0';
if DI'EVENT and DI = '1' then Nextstate <= S7;
elsif HI'EVENT and HI = '1' then Nextstate <= S5;
elsif QI'EVENT and QI = '1' then Nextstate <= S4;
elsif rst'EVENT and rst = '1' then Nextstate <= S10;
else Nextstate <= S3; end if;
when S4 =>
DO <= '0'; HO <= '0'; QO <= '0'; ST <= '0';
if DI'EVENT and DI = '1' then Nextstate <= S8;
elsif HI'EVENT and HI = '1' then Nextstate <= S6;
elsif QI'EVENT and QI = '1' then Nextstate <= S5;
elsif rst'EVENT and rst = '1' then Nextstate <= S10;
else Nextstate <= S4; end if;
when S5 =>
DO <= '0'; HO <= '0'; QO <= '0'; ST <= '0';
if DI'EVENT and DI = '1' then Nextstate <= S9;
elsif HI'EVENT and HI = '1' then Nextstate <= S7;
elsif QI'EVENT and QI = '1' then Nextstate <= S6;
elsif rst'EVENT and rst = '1' then Nextstate <= S10;
else Nextstate <= S5; end if;
when S6 =>
DO <= '0'; HO <= '0'; QO <= '0'; ST <= '0';
Nextstate <= S11;
when S7 =>
DO <= '0'; HO <= '0'; QO <= '1'; ST <= '0';
QOint <= -1;
Nextstate <= S11;
when S8 =>
DO <= '0'; HO <= '1'; QO <= '0'; ST <= '0';
HOint <= HOint -1;
Nextstate <= S11;
when S9 =>
DO <= '0'; HO <= '1'; QO <= '1'; ST <= '0';
HOint <= HOint -1;
QOint <= QOint -1;
Nextstate <= S11;
when S10 =>
DOint <= 9; HOint <= 9; QOint <= 9; STint <= 9;
Nextstate <= S0;
when others => null;
end case;
end process;
process(CLK1)
begin
if CLK1'EVENT and CLK1 = '1' then
State <= Nextstate;
end if;
end process;
process(state,CLK2)
begin
case State is
when S11 =>
DO <= '0'; HO <= '0'; QO <= '0'; ST <= '1';
if CLK2'EVENT and CLK2 = '1' then STint <= STint -1;
elsif STint <= 0 then Nextstate <= S0; end if;
when others => null;
end case;
end process;
I've tried many alternatives, such as using the CLK1 as the clock for the STint decreasement, but it didn't work well because the other int(s) will decrease again and again.
For further information, this FSM is actually similar to vending machine, except in S11, a timer will start the countdown then go to the next state, which is S0. The other states is just for the inputs (such as the money) and the outputs (such as the changes). In S11, the ST LED will be turned on as long as the timer still counting down.
Is there any way I can achieve this? I would really glad if someone could point me out why my code won't work. It seems like whenever the machine is in S11, it cannot change its state. This is how my code looks like in TINA:
Thank you very much. Have a nice day!
PS: The timer is shown in STcount outputs
You have some issues in your approach:
Multiple clocks for the FSM. You should avoid to have multiple clocks in your designs and use it only when necessary. To have two clocks for a given circuit is ask for problems.
Use a single clock. If you want to keep the control using the clock build a separate circuit to control just the clock generation. A counter can solve for a simple design. More complex design may require the use of specific hardware for clock generation(e.g PLL).
You are assigning to signals in different process at least DO. This should not synthesize.
I suggest you to rethink your state machine control and to understand the limits for the decreasing speed.

Train Ticket Machine in VHDL

I am new in VHDL. I try to create train ticket machine using vhdl. It have 3 destination and all destination have fee. When user insert money with same of fee, ticket will out and no change but if user enter extra money than fee, ticket will out also with change.When i run the simulation all output does not appear correctly but only come out with uuu. Anybody can help me with my code below, please.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity trainticket_machine is
PORT( Clock,Reset,Cancel : IN STD_LOGIC;
RM1,RM2,RM5 : IN STD_LOGIC;
KL_station,Mid_station,Klang_station : IN STD_LOGIC;
Ticket : OUT STD_LOGIC;
Change,Retrn : OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
Money_sum : INOUT STD_LOGIC_VECTOR (3 DOWNTO 0)
);
end trainticket_machine;
architecture Behavioral of trainticket_machine is
TYPE state IS (S0,S1,S2,S3,S4,S5,S6,S7,S8,S9,Cancl,waiting1,waiting2,waiting3,KL_Ticket,Mid_Ticket,Shah_Ticket);
SIGNAL p_state,Train_state: STATE;
BEGIN
PROCESS(Reset,Clock)
BEGIN
IF (Reset = '1') THEN
p_state <= S0;
Ticket <= '0';
Retrn <= "0000";
Money_sum <= "ZZZZ";
ELSIF (Clock'EVENT AND Clock = '1') THEN
p_state <= Train_state;
END IF;
END PROCESS;
PROCESS (p_state,Cancel,RM1,RM2,RM5,KL_station,Mid_station,Klang_station)
BEGIN
CASE p_state IS
WHEN S0 =>
Money_sum <= "0000";
Change <= "0000";
IF (KL_station = '1') THEN Train_state <= waiting1;
ELSIF(Mid_station = '1') THEN Train_state <= waiting2;
ELSIF(Klang_station = '1') THEN Train_state <= waiting3;
ELSE Train_state <= S0;
END IF;
WHEN waiting1 =>
Ticket <= '0';
Change <= "0000";
IF (RM1 = '1') THEN Train_state <= S1;
ELSIF (RM2 = '1') THEN Train_state <= S2;
ELSIF (RM5 = '1') THEN Train_state <= S3;
ELSIF (Money_sum >= 2) THEN train_state <= KL_Ticket;
ELSIF (Cancel = '1') THEN Train_state <= Cancl;
ELSE Train_state <= waiting1;
END IF;
WHEN waiting2 =>
Ticket <= '0';
Change <= "0000";
IF (RM1 = '1') THEN Train_state <= S4;
ELSIF (RM2 = '1') THEN Train_state <= S5;
ELSIF (RM5 = '1') THEN Train_state <= S6;
ELSIF (Money_sum >= 4) THEN train_state <= Mid_Ticket;
ELSIF (Cancel = '1') THEN Train_state <= Cancl;
ELSE Train_state <= waiting2;
END IF;
WHEN waiting3 =>
Ticket <= '0';
Change <= "0000";
IF (RM1 = '1') THEN Train_state <= S7;
ELSIF (RM2 = '1') THEN Train_state <= S8;
ELSIF (RM5 = '1') THEN Train_state <= S9;
ELSIF (Money_sum >= 6) THEN train_state <= Shah_Ticket;
ELSIF (Cancel = '1') THEN Train_state <= Cancl;
END IF;
WHEN S1 =>
IF (RM1 <= '1' AND RM2 <= '0' AND RM5 <= '0') THEN
Ticket <= '0';
Change <= "0000";
Money_sum <= Money_sum + 1;
ELSE Train_state <= waiting1;
END IF;
WHEN S2 =>
IF (RM1 <= '1' AND RM2 <= '1' AND RM5 <= '0') THEN
Ticket <= '1';
Change <= "0000";
Money_sum <= Money_sum + 2;
ELSE Train_state <= waiting1;
END IF;
WHEN S3 =>
IF (RM1 <= '0' AND RM2 <= '0' AND RM5 <= '1') THEN
Ticket <= '1';
Change <= "0001";
Money_sum <= Money_sum + 5;
ELSE Train_state <= waiting1;
END IF;
WHEN S4 =>
IF (RM1 <= '1' AND RM2 <= '0' AND RM5 <= '0') THEN
Ticket <= '0';
Change <= "0000";
Money_sum <= Money_sum + 1;
ELSE Train_state <= waiting2;
END IF;
WHEN S5 =>
IF (RM1 <= '0' AND RM2 <= '1' AND RM5 <= '0') THEN
Ticket <= '0';
Change <= "0000";
Money_sum <= Money_sum + 2;
ELSE Train_state <= waiting2;
END IF;
WHEN S6 =>
IF (RM1 <= '0' AND RM2 <= '0' AND RM5 <= '1') THEN
Ticket <= '0';
Change <= "0001";
Money_sum <= Money_sum + 5;
ELSE Train_state <= waiting2;
END IF;
WHEN S7 =>
IF (RM1 <= '1' AND RM2 <= '0' AND RM5 <= '0') THEN
Ticket <= '0';
Change <= "0000";
Money_sum <= Money_sum + 1;
ELSE Train_state <= waiting3;
END IF;
WHEN S8 =>
IF (RM1 <= '0' AND RM2 <= '1' AND RM5 <= '0') THEN
Ticket <= '0';
Change <= "0000";
Money_sum <= Money_sum + 2;
ELSE Train_state <= waiting3;
END IF;
WHEN S9 =>
IF (RM1 <= '0' AND RM2 <= '0' AND RM5 <= '1') THEN
Ticket <= '0';
Change <= "0000";
Money_sum <= Money_sum + 5;
ELSE Train_state <= waiting3;
END IF;
WHEN KL_Ticket =>
Ticket <= '1';
Change <= Money_sum - 2;
Train_state <= waiting1;
WHEN Mid_Ticket =>
Ticket <= '1';
Change <= Money_sum - 4;
Train_state <= waiting2;
WHEN Shah_Ticket =>
Ticket <= '1';
Change <= Money_sum - 6;
Train_state <= waiting3;
WHEN Cancl =>
IF (Cancel <= '1') THEN
Retrn <= Money_sum;
ELSE Train_state <= S0;
END IF;
END CASE;
END PROCESS;
end Behavioral;
------------------------------simulation----------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_arith.all;
ENTITY trainticket_machine_tb IS
END trainticket_machine_tb;
ARCHITECTURE behavior OF trainticket_machine_tb IS
Signal Clock,Reset,Cancel,RM1,RM2,RM5,KL_station,Mid_station,Klang_station : std_logic := '0';
Signal Ticket : std_logic ;
signal Change,Retrn,Money_sum : std_logic_vector(3 downto 0);
constant Clock_period : time := 10 ns;
BEGIN
uut: entity work.trainticket_machine PORT MAP (
Clock => Clock,
Reset => Reset,
Cancel => Cancel,
RM1 => RM1,
RM2 => RM2,
RM5 => RM5,
KL_station => KL_station,
Mid_station => Mid_station,
Klang_station => Klang_station,
Ticket => Ticket,
Change => Change,
Retrn => Retrn,
Money_sum => Money_sum
);
Clock_process :process
begin
Clock <= '0';
wait for Clock_period/2;
Clock <= '1';
wait for Clock_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
wait for Clock_period*2;
Reset <= '1';
wait for Clock_period;
Reset <= '0';
wait for Clock_period;
Cancel <= '1';
wait for Clock_period;
Cancel <= '0';
wait for Clock_period;
KL_station <= '1';
wait for Clock_period;
KL_station <= '0';
wait for Clock_period;
Mid_station <= '1';
wait for Clock_period;
Mid_station <= '0';
wait for Clock_period;
Klang_station <= '1';
wait for Clock_period;
Klang_station <= '0';
wait for Clock_period;
RM1 <= '1';
wait for Clock_period;
RM1 <= '0';
wait for Clock_period;
RM2 <= '1';
wait for Clock_period;
RM2 <= '0';
wait for Clock_period;
RM5 <= '1';
wait for Clock_period;
RM5 <= '0';
wait for Clock_period;
wait;
end process;
END;
Starting with the first problem you describe: since you are seeing only 'U's, maybe your outputs were never assigned any value. Did you remember to force Reset to '1' in the beginning of the simulation?
Now let's take a look at the state machine logic itself, which has many problems. First thing: you should differentiate between combinational logic and registered state. By state I mean values that must be kept in registers of flip-flops, between the clock transitions.
This is important because for each process you will have to decide whether it is combinational or registered. If the process is registered, it must be sensitive to your clock. If the process is combinational, it cannot have any statements that woud imply keeping state information.
So the first suggestion is to go through your code, and decide the nature of each process you have. You may have to create a few more processes, it's ok. From your code, it looks like the signal money_sum is state information, and therefore it should be updated on the rising edge of clock.
The second suggestion is: if you have an output that depends only on the current state (maybe your signal ticket), you need to assign a value to this signal on every condition of your case statement. Try removing the line Ticket <= '0'; from your first process and see what happens.
Third, please use more descriptive names for your states and signals, it is really hard to understand what is going on from names like S0, S1, S2, RM1, RM2, and RM5.
Finally, it would be really helpful to have some assertions in your testbench code. For instance, after every wait for Clock_period;, you could check your outputs to make sure they match what you expected:
Reset <= '1';
wait for Clock_period;
assert ticket = '0' report "Wrong value for 'ticket' after reset";
assert change = "0000" report "Wrong value for 'change' after reset";
assert retrn = "0000" report "Wrong value for 'retrn' after reset";
assert money_sum = "0000" report "Wrong value for 'money_sum' after reset";

VHDL change CLK speed

From this code I create a block, then add CLK, KEY[0] and LEDR[0:15]
library ieee;
use ieee.std_logic_1164.all;
--library work;
--use work.car_pkg.all;
entity knight_rider2 is
port ( clk, resetn, clock_button : in std_logic;
led1, led2, led3, led4, led5, led6, led7, led8,
led9, led10, led11, led12, led13, led14, led15 : out std_logic);
end entity knight_rider2;
architecture fsm of knight_rider2 is
type state_types is (start, forward1, forward2, forward3,
forward4, forward5, forward6, forward7, forward8, forward9,
forward10,forward11,forward12, forward13, forward14);
signal state: state_types;
signal led_states : std_logic_vector(14 downto 0);
begin
count : process(clk, resetn, clock_button)
begin
if clock_button = '0' then
counter <= 0;
fsm_pulse <= '0';
else
if rising_edge(clk) then
counter <= counter + 1;
fsm_pulse <= '0';
if counter = divider then
fsm_pulse <= '1';
counter <= 0;
end if;
end if;
end if;
end process;
combined_next_current: process (clk, resetn, clock_button)
begin
if (resetn = '0') then
state <= start;
elsif rising_edge(clk) then
if fsm_pulse = '1' then
case state is
when start =>
state <= forward1;
when forward1 =>
state <= forward2;
when forward2 =>
state <= forward3;
when forward3 =>
state <= forward4;
when forward4 =>
state <= forward5;
when forward5 =>
state <= forward6;
when forward6 =>
state <= forward7;
when forward7 =>
state <= forward8;
when forward8 =>
state <= forward9;
when forward9 =>
state <= forward10;
when forward10 =>
state <= forward11;
when forward11 =>
state <= forward12;
when forward12 =>
state <= forward13;
when forward13 =>
state <= forward14;
when forward14 => state <=start;
when others =>
state <= forward1;
end case;
end if;
end process;
--combinational output logic
--internal signal to control state machine transistions
led_select : process(state)
begin
case state is
when forward1 =>
led_states <= "000000000000011";
when forward2 =>
led_states <= "000000000000110";
when forward3 =>
led_states <= "000000000001100";
when forward4 =>
led_states <= "000000000011000";
when forward5 =>
led_states <= "000000000110000";
when forward6 =>
led_states <= "000000001100000";
when forward7 =>
led_states <= "000000011000000";
when forward8 =>
led_states <= "000000110000000";
when forward9 =>
led_states <= "000001100000000";
when forward10 =>
led_states <= "000011000000000";
when forward11=>
led_states <= "000110000000000";
when forward12=>
led_states <= "001100000000000";
when forward13=>
led_states <= "011000000000000";
when forward14=>
led_states <= "110000000000000";
when others =>
led_states <= "100000000000001";
end case;
end process;
led1 <= led_states(0);
led2 <= led_states(1);
led3 <= led_states(2);
led4 <= led_states(3);
led5 <= led_states(4);
led6 <= led_states(5);
led7 <= led_states(6);
led8 <= led_states(7);
led9 <= led_states(8);
led10 <= led_states(9);
led11 <= led_states(10);
led12 <= led_states(11);
led13 <= led_states(12);
led14 <= led_states(13);
led15 <= led_states(14);
end;
But now I want add KEY[1] button to change speed, for example:
1st press : 2*f
2 press: 4*f
3 press: 8*f
4 press: f
5 press: 2*f etc
So, how can I change this code to do what I want?
You can change the rate that your state machine operates at by employing a counter, for example:
-- Generate a counter at your main clock frequency
-- counter is declared as an integer.
count : process(clock, resetn)
begin
if resetn = '0' then
counter <= 0;
fsm_pulse <= '0';
else
if rising_edge(clock) then
counter <= counter + 1;
fsm_pulse <= '0';
if counter = divider then
fsm_pulse <= '1';
counter <= 0;
end if;
end if;
end if;
end process;
The new signals are declared as follows:
signal fsm_pulse : std_logic;
signal counter : integer;
signal divider : integer;
Then, in your FSM process you can trigger state transitions using the fsm_pulse you generated:
combined_next_current: process (clk, resetn)
begin
if (resetn = '0') then
state <= start;
elsif rising_edge(clk) then
if fsm_pulse = '1' then
case state is
when start =>
state <= forward1;
when forward1 =>
state <= forward2;
...
etc (your remaining states)
end if;
The fsm_pulse will be set to '1' for a single clock cycle whenever the counter reaches the divider value you have chosen. The divider value represents the number of clock cycles you desire each FSM transition to occur after, for example a divider of zero will make the FSM transition at the main clock frequency and a divider of 1 will make the FSM transition at halve the main clock frequency.

Resources