I'm running the code in edaplayground because that's the required site we should use.
this is my vhdl code idk why it doesnt work:
-- Testbench for the counter design
entity counter_tb is
end entity;
architecture sim of counter_tb is
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal count : std_logic_vector(2 downto 0);
begin
-- Instantiate the design under test
dut: entity work.counter
port map (
clk => clk,
reset => reset,
count => count
);
-- Clock process to generate a clock signal
clk_process : process
begin
clk <= '0';
wait for 5 ns;
clk <= '1';
wait for 5 ns;
end process;
-- Stimulus process to reset the counter and generate test sequences
stim_process : process
begin
wait for 10 ns;
reset <= '1';
wait for 5 ns;
reset <= '0';
wait for 10 ns;
assert count = "000";
wait for 10 ns;
assert count = "001";
wait for 10 ns;
assert count = "011";
wait for 10 ns;
assert count = "110";
wait for 10 ns;
assert count = "111" ;
wait for 10 ns;
assert count = "000";
end process;
end
the design:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity counter is
Port ( clk : in STD_LOGIC;
reset : in STD_LOGIC;
count : out STD_LOGIC_VECTIC(2 downto 0));
end counter;
architecture Behavioral of counter is
type states is (s0, s1, s3, s6, s7);
signal current_state, next_state : states;
begin
process(clk, reset)
begin
if reset = '1' then
current_state <= s0;
elsif rising_edge(clk) then
current_state <= next_state;
end if;
end process;
count <= "000" when current_state = s0 else
"001" when current_state = s1 else
"011" when current_state = s3 else
"110" when current_state = s6 else
"111" when current_state = s7;
next_state <= s1 when current_state = s0 else
s3 when current_state = s1 else
s6 when current_state = s3 else
s7 when current_state = s6 else
s0 when current_state = s7;
end Behavioral;
i tried searching on youtube but i still cant fix it also i tried following the ims our prof gave us but still cant fix it. what i need to do is to make the count like 0 1 3 6 7 0 1 ... in the ep wave
I am fairly new to VHDL and am following this tutorial to implement the following Mealy Finite State Machine:
and have written the following code in VHDL:
library ieee;
use ieee.std_logic_1164.all;
entity fsm is
port(clk, rst, in1 : in std_logic; o1 : out std_logic);
end fsm;
architecture mealy of fsm is
type state is (state1, state2);
signal current_state, next_state : state;
begin
comb: process(current_state, in1) begin
next_state <= current_state; -- default case
case current_state is
when state1 =>
o1 <= '0';
if in1 = '1' then
o1 <= '1';
next_state <= state2;
end if;
when state2 =>
o1 <= '1';
if in1 = '0' then
o1 <= '0';
next_state <= state1;
end if;
end case;
end process;
mem: process(clk, rst) begin
if rst = '1' then
current_state <= state1;
else
current_state <= next_state;
end if;
end process;
end mealy;
However on applying the following testbench:
library ieee;
use ieee.std_logic_1164.all;
entity fsm_tb is
end fsm_tb;
architecture sim of fsm_tb is
constant clockperiod : time := 10 ns; -- 100 Mhz clock
signal clk : std_logic := '0';
signal rst : std_logic;
signal in1, o_mealy : std_logic;
begin
uut_mealy : entity work.fsm(mealy) port map( clk => clk, rst => rst, in1 => in1, o1 => o_mealy);
clk <= not clk after clockperiod/2;
process begin
-- initial reset
in1 <= '0';
rst <= '1';
wait until rising_edge(clk);
-- take device out of reset
rst <= '0';
-- apply same inputs to both the devices
in1 <= '0'; wait for 23 ns;
in1 <= '1'; wait for 32 ns;
in1 <= '0'; wait for 7 ns;
in1 <= '1'; wait for 15 ns;
wait;
end process;
end sim;
the waveforms that I have obtained do not make sense to me:
As you can see the output o_mealy changes even without clock edge. It simply seems to only be following the input. By contrast, I have implemented the equivalent Moore machine and it seems to be working just fine:
If anyone can point out what I am doing wrong, it would be highly appreciated. Again, I have used this video for reference. I am using GHDL with GTKWave.
Taking a look at your concurrent logic:
case current_state is
when state1 =>
o1 <= '0';
if in1 = '1' then
o1 <= '1';
next_state <= state2;
end if;
when state2 =>
o1 <= '1';
if in1 = '0' then
o1 <= '0';
next_state <= state1;
end if;
end case;
In any of the two states, if in1 = '1', the output is 1, if in1 = '0' the output is 0. So the FSM works fine, but looking from the outside in you just cannot see the difference between the two states.
In terms of what are you doing wrong: I think this is correct, actually, looking at your drawing. In a mealy machine, the output is depended on the current state and the current input, which is exactly what is happening here.
Using GHDL's GHW dump file format to allow gtkwave to display enumerated type values we see:
where in current_state is being updated on both edges of clock (in a manner not likely supported for synthesis).
That can be corrected by evaluating a single clock edge in a manner conducive to synthesis:
mem: process(clk, rst) begin
if rst = '1' then
current_state <= state1;
elsif rising_edge(clk) then -- evaluate clock edge
current_state <= next_state;
end if;
end process;
And that gives us
current_state transitioning on one clock edge only.
I am making a FSM Moore sequence detector on VHDL for a given input bit sequence (10100110) but now I also want to add an even parity bit to the input bit sequence as a new sequence. I know the logic behind it to use xor gate but im unable to implement it in the code.
This is my design code:
library IEEE;
use IEEE.std_logic_1164.all;
entity sequence_detector is
port(clock: in std_logic;
input_seq: in std_logic;
detector: out std_logic);
end sequence_detector;
architecture behaviour of sequence_detector is
type state is (init, s1, s2, s3, s4);
signal p_s, n_s : state;
begin
process
begin
wait until clock'event and clock = '1';
p_s <= n_s;
end process;
process (input_seq, p_s)
begin
case(p_s) is
when init =>
if(input_seq = '1') then
n_s <= s1;
detector <= '0';
else
n_s <= init;
detector <= '0';
end if;
when s1 =>
if(input_seq = '0') then
n_s <= s2;
detector <= '0';
else
n_s <= s1;
detector <= '0';
end if;
when s2 =>
if(input_seq = '0') then
n_s <= s3;
detector <= '0';
else
n_s <= s1;
detector <= '0';
end if;
when s3 =>
if(input_seq = '1') then
n_s <= s4;
detector <= '0';
else
n_s <= init;
detector <= '0';
end if;
when s4 => --here we decide if its overlapping or not
if(input_seq = '1') then
n_s <= s1;
detector <= '1';
else
n_s <= s2;
detector <= '0';
end if;
end case;
end process;
end behaviour;
This is my testbench:
library IEEE;
use IEEE.std_logic_1164.all;
entity testbench is
end testbench;
architecture behaviour of testbench is
component sequence_detector is
port(clock: in std_logic;
input_seq: in std_logic;
detector: out std_logic);
end component;
signal clock, input_seq : std_logic;
signal detector : std_logic;
constant clock_period: Time := 10 ns;
begin
DUT: sequence_detector port map(clock, input_seq, detector);
p_clock: process
begin
clock <= '0';
wait for clock_period/2;
clock <= '1';
wait for clock_period/2;
end process;
process
begin
input_seq <= '1';
wait for 10 ns;
input_seq <= '0';
wait for 10 ns;
input_seq <= '1';
wait for 20 ns;
input_seq <= '0';
wait for 20 ns;
input_seq <= '1';
wait for 20 ns;
input_seq <= '0';
wait;
end process;
end behaviour;
This is the output:
output graph
I hate to ask yet another question on here but apparently I'm really useless with simulators :(.
Basically, I have a traffic light controller that is made up of a bunch of different states and a few timers running for different lengths of time. When the system enters a state, it activates a timer and there is an if statement that watches the timer output and points the system to the next state when the timer output value is 1.
This all works fine on the board, but when I simulate it the count ticks to '1' but the next state isn't selected. This can be seen, here:
I've tried to boil the code down into the essentials below, but if you need more context (and are feeling far more generous than I deserve) then the full code is here.
Initialisation:
entity trafficlightcontroller is
port
(
clk : in std_logic;
reset : in std_logic;
ambulance : in std_logic;
smr : in std_logic;
sml : in std_logic;
ssr : in std_logic;
rlmr : out std_logic;
almr : out std_logic;
glmr : out std_logic;
rlsr : out std_logic;
alsr : out std_logic;
glsr : out std_logic
);
end entity;
architecture rtl of trafficlightcontroller is
-- Build an enumerated type for the state machine
-- r=red;a=amber;g=green;c=car waiting;m=main road;s=side road
type state_type is (rmgs, rmas, rmrs, amrs, gmrs, gmrcs, ramrs, rmacs, rmrcs, ramrcs, rmras, rmrs2);
-- Signals to hold the states
signal present_state, next_state : state_type;
signal divclk, reset2, reset2b, reset3, reset3b, reset10, reset20, reset20b, count2, count2b, count3, count3b, count10, count20, count20b: std_logic;
component timer is
generic (
trigger_cnt: natural := 20
);
port (
clk: in std_logic;
reset: in std_logic;
count: buffer std_logic
);
end component timer;
component clockdivider
port(clkin : in std_logic;
dividedclk : out std_logic
);
end component clockdivider;
begin
timer2 : timer generic map (trigger_cnt => 2) port map(divclk,reset2,count2);
timer2b : timer generic map (trigger_cnt => 2) port map(divclk,reset2b,count2b);
timer3 : timer generic map (trigger_cnt => 3) port map(divclk,reset3,count3);
timer3b : timer generic map (trigger_cnt => 3) port map(divclk,reset3b,count3b);
timer10 : timer generic map (trigger_cnt => 10) port map(divclk,reset10,count10);
timer20 : timer generic map (trigger_cnt => 20) port map(divclk,reset20,count20);
timer20b : timer generic map (trigger_cnt => 20) port map(divclk,reset20b,count20b);
divider : clockdivider port map(clk, divclk);
The beginning of the states (including the state shown in the simulation):
case present_state is
--Red light main; green side road
when rmgs=>
reset2 <= '0';
reset2b <= '0';
reset3 <= '0';
reset3b <= '0';
reset20 <= '0';
reset20b <= '0';
rlmr <= '1';
almr <= '0';
glmr <= '0';
rlsr <= '0';
alsr <= '0';
glsr <= '1';
reset10 <= '1';
--if count is complete then move to next state
if ( count10='1' ) THEN
next_state <= rmas;
--otherwise, return to current state
else
next_state <= rmgs;
end if;
Clock process:
--Every clock tick, the next state is selected as the present state.
state_clocked: process(clk)
begin
if ( rising_edge( clk ) ) THEN
present_state <= next_state;
end if;
end process state_clocked;
The line I entered into the simulator to initialise the clock:
force clk 0 0ns, 1 10 ns -repeat 20ns
Your next_state process is missing lots of signals in the sensitivity list. This will probably fix it. VHDL-2008 allows you to use the keyword "all" instead of signal names. If your synthesis tool supports this, it might be worth using.
The rest are suggestions:
With a two process statemachine, reset logic is most often captured in the state_clocked process. And hence, look more like this:
state_clocked: process(clk)
begin
if ( rising_edge( clk ) ) THEN
if Reset = '0' then
present_state <= rmrs;
else
present_state <= next_state;
end if ;
end if;
end process state_clocked;
You can shorten your code significantly if you use a default assignment to assign the "off" value to all signal outputs of the next_state process:
next_state_proc : process (present_state, ssr, ambulance, Count10, Count3, ... )
begin
-- default assignments
reset2 <= '0';
reset2b <= '0';
reset3 <= '0';
reset3b <='0';
reset10 <= '0';
reset20 <= '0';
reset20b <= '0';
rlmr <= '1';
almr <= '0';
glmr <= '0';
rlsr <= '1';
alsr <= '0';
glsr <= '0';
next_state <= present_state ; -- optional
-- Statemachine code starts here
-- Only do assignments that are different from the default.
if ssr = '0' then
-- Do you change the values from the defaults here?
-- with the defaults, it is not necessary to do any assignments here, however,
-- without the defaults these outputs would have latches on them.
case present_state is
when gmrs => next_state <= gmrcs;
when rmas => next_state <= rmacs;
...
end case ;
elsif ambulance = '0' then
-- Do you change the values from the defaults here?
-- with the defaults, it is not necessary to do any assignments here, however,
-- without the defaults these outputs would have latches on them.
case present_state is
when gmrs | ramrs | ramrcs => next_state <= amrs;
-- when rmas => ???
when rmgs | rmras => next_state <= rmas;
...
end case ;
else
-- main statemachine
case present_state is
when rmgs=>
-- Only drive outputs that are different from the defaults here.
rlsr <= '0';
glsr <= '1';
reset10 <= '1';
--if count is complete then move to next state
if ( count10='1' ) THEN
next_state <= rmas;
--otherwise, return to current state
else
next_state <= rmgs;
end if;
when rmas=>
. . .
end case ;
The reset for the present_state register isn't strictly needed for simulation, but should be there for synthesis.
state_clocked:
process(reset,clk)
begin
if reset = '0' then
present_state <= rmrs;
elsif rising_edge( clk ) THEN
present_state <= next_state;
end if;
end process;
(Jim beat me to it).
process (present_state, reset, ssr, ambulance, count2, count2b,
count3, count3b, count10, count20, count20b)
Adding the process sensitivity elements (and using reset):
(I added a bit more to it. A lot of your design appears to be working to a good extent.)
And think about using a test bench, it would allow automated testing by generating inputs on ambulance, smr, sml and ssr.
library ieee;
use ieee.std_logic_1164.all;
entity tb_tfc is
end entity;
architecture foo of tb_tfc is
signal clk: std_logic := '0';
signal reset: std_logic;
signal ambulance: std_logic := '1';
signal smr: std_logic := '1';
signal sml: std_logic := '1';
signal ssr: std_logic := '1';
signal rlmr: std_logic;
signal almr: std_logic;
signal glmr: std_logic;
signal rlsr: std_logic;
signal alsr: std_logic;
signal glsr: std_logic;
begin
DUT:
entity work.trafficlightcontroller
port map (
clk,
reset,
ambulance,
smr,
sml,
ssr,
rlmr, -- out
almr, -- out
glmr, -- out
rlsr, -- out
alsr, -- out
glsr -- out
);
CLOCK:
process
begin
wait for 10 ns;
clk <= not clk;
if Now > 1280 ns then
wait;
end if;
end process;
STIMULUS:
process
begin
reset <= '0'; --
wait for 20 ns;
reset <= '1';
wait for 1020 ns;
ssr <= '0';
wait;
end process;
end architecture;
i'm in the process of configuring an RS232 to USB cable with VHDL and i seem to have a problem. I don't know how to configure a dual-port RAM. I have attempted searching on answers to that and i found some code but i don't completely understand how to apply this code. This code can be found in this link --> http://www.asic-world.com/examples/vhdl/ram_dp_ar_aw.html.
Please help as soon as possible, i'm in desperate need of this information.
----------------------------------------------------------------------------------
-- Create Date : 14:06:22 12/08/2013
-- Designer Name : Sarin anand k
-- Module Name : UART - Behavioral
-- Project Name : RS232 transmitter
----------------------------------------------------------------------------------
-- spartan 3 starter kit
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_unsigned.all;
library UNISIM;
use UNISIM.VComponents.all;
entity uart is
port(
sys_clk : in std_logic; --50Mhz
reset : in std_logic;
data_in : in std_logic_vector(7 downto 0); -- switch
load : in std_logic; --push button
Tx : out std_logic
);
end uart;
architecture Behavioral of uart is
type T_state is (IDLE,STORAGE,START, DATA, STOP);
-- baud rate = 115200, bit duration required is 1/115200 = 8680 ns
-- for a 50MHz clock, period is 20 ns. So each bit is 8680/20 = 434 clock cycles
constant bit_dur : std_logic_vector(15 downto 0) := X"01B3"; -- 434 clocks
constant start_bit : std_logic := '0';
constant stop_bit : std_logic := '1';
signal baud_cnt : std_logic_vector(23 downto 0) := X"000000"; -- 115200
signal baud_en : std_logic;
signal temp : std_logic_vector(7 downto 0);
signal baud_rate_cnt : std_logic_vector(7 downto 0):=(others => '0');
signal bit_cnt_start : std_logic;
signal baud_flag : std_logic;
signal state : T_state;
begin
-----------------------------------------------------------------------------------------------------
---- baud clock
------------------------------------------------------------------------------------------------------
baud_rate: process(sys_clk) begin
if rising_edge(sys_clk) then
if (reset = '1') then
baud_cnt <= X"000000";
baud_en <= '0';
end if;
if (baud_cnt = bit_dur)then
baud_en <= '1'; -- data in flag
baud_cnt <= X"000000";
elsif(bit_cnt_start = '1') then
baud_cnt<= baud_cnt + '1';
baud_en <= '0';
end if;
end if;
end process baud_rate;
---------------------------------------------------------------------------------------------------------------
-- baud clock counter
----------------------------------------------------------------------------------------------------------------
baud_counter: process(sys_clk) begin
if(rising_edge (sys_clk)) then
if(reset = '1') then
baud_rate_cnt <=( others => '0');
baud_flag <= '0';
end if;
if( baud_rate_cnt = "1000") then
baud_flag <= '1';
baud_rate_cnt <=( others => '0');
elsif( state = DATA and baud_en ='1') then
baud_rate_cnt <= baud_rate_cnt + '1';
baud_flag <= '0';
end if;
end if;
end process baud_counter;
--------------------------------------------------------------------------------------------------------------------
-- State machine to control the data flow
----------------------------------------------------------------------------------------------------------------------
control_flow: process (sys_clk) begin
if(rising_edge (sys_clk)) then
if (reset = '1') then
bit_cnt_start <= '0';
state <= IDLE;
end if;
case state is
when IDLE =>
state <= STORAGE;
when STORAGE =>
if (load = '1') then
state <= START;
bit_cnt_start <= '1';
end if;
when START =>
if (baud_en ='1') then
state <= DATA;
end if;
when DATA =>
if ((baud_en ='1') and (baud_flag = '1')) then
state <= STOP;
end if;
when STOP =>
if (baud_en = '1') then
state <= IDLE;
bit_cnt_start <= '0';
end if;
when others =>
state <= IDLE;
end case;
end if;
end process control_flow;
------------------------------------------------------------------------------------------------------------------------
-- Data Transmission
-------------------------------------------------------------------------------------------------------------------------
data_trans: process (sys_clk) begin
if (rising_edge(sys_clk)) then
if (reset = '1') then
temp <= (others => '0');
end if;
-- Data Mux
case state is
when IDLE =>
temp <= (others => '0');
when STORAGE =>
temp <= data_in;
when START =>
Tx <= start_bit;
when DATA =>
Tx <= temp(0);
if ( baud_en = '1') then
temp <= '0' & temp(7 downto 1) ;
Tx <= temp(0);
end if;
when STOP =>
Tx <= stop_bit;
when others =>
Tx <= '1';
end case;
end if;
end process data_trans;
end Behavioral;