How to make a process that executes only once on powering up?
It is easy to make a process that executes when reset button is pressed, but how to make it run when you plug in the power supply without touching the reset button?
In my example I want to initialize the LCD on startup and I need to send some commands to it in the beginning, but I don't need it in the process that is dependent on some signal like reset(just let's suppose there is no reset button at all).
The state (first run) is stored in a single FF, which is initialized with '1':
signal IsStartup : STD_LOGIC := '1';
FF process without reset:
process(clk)
begin
if rising_edge(clk) then
IsStartup <= '0';
end if;
end process;
Usage example (FSM):
process(clk)
begin
if rising_edge(clk) then
if (Reset = '1') then
State <= ST_RESET;
else
State <= NextState;
end if;
end if;
end process;
process(State, IsStartup)
begin
NextState <= State;
case State is
when ST_RESET =>
if (IsStartup = '1') then
NextState <= ST_STARTUP;
else
NextState <= ST_IDLE;
end if;
-- ...
end case;
end process;
Just use a wait statement with no sensativity list.
process
begin
assignment <= "101";
wait;
end process;
That being said, I'd recommend that you instead build this as a state machine.
Related
I'm trying to create a simple push button in VHDL that turns on after an input switch or pb goes from 0 to 1 to 0 using a clock and a process. However, my code seems to be giving me undefined output. Here's what I have so far.
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
Entity captureInput is port
(
CLK : in std_logic := '0';
RESET_n : in std_logic := '0';
buttonState : in std_logic := '0';
buttonOut : out std_logic := '0'
);
end Entity;
ARCHITECTURE one of captureInput is
signal lastButtonState: std_logic := '0';
signal btnState : std_logic := '0';
BEGIN
process (CLK, RESET_n) is
begin
if (RESET_n = '0') then
lastButtonState <= '0';
elsif (rising_edge(CLK)) then
if (buttonState ='0' and lastButtonState = '1') then
btnState <= '1';
end if;
lastButtonState <= buttonState;
end if;
end process;
buttonOut <= btnState
end;
Try to initialize your btnState in the reset branch of your register and also have an else statement where you set your btnState back to 0, under some condition. I would bet that your undefined output comes from the fact that you do not define your btnState anywhere else outside your if conditions. It's good practice to not rely on the initial value of your declaration: Synthesis tools ignore it and some simulators will as well. Also, remember that the clocked body of the if will generate a register for every signal that gets assigned a value inside it, and that signals will keep the last value assigned to them inside a process.
You are also missing the Library ieee; statement at the top and a semicolon after buttonOut <= btnState.
Reading a button do need a debouncer.
Please take a look at:
VHDLWhiz generate statement
or
VHDLWhiz How to read a button in VHDL
Even though I see that you have already accepted Dimitris' answer, I can add that your code is almost right, you just need to toggle on the falling edge of of the latch instead of setting it to '1' as you do.
Try
if(rising_edge(CLK)) then
lastButtonState <= buttonState;
if(buttonState='0' and lastButtonState='1') then
btnState <= not btnState;
end if;
end if;
buttonOut <= btnState -- etc...
You don't need to initialize anything to '0' but you DEFINITELY need a switch debouncer as lukipedio said otherwise your toggle will not be consistent.
If you think about it, what you're doing is putting a "clock divider" on your lastButtonState register by toggling in order to set the btnState register at half the "frequency" of lastButtonState, which is what you want.
BTW, if you switch your toggling condition to
(buttonState='1' and lastButtonState='0')
then it will toggle on the rising edge of lastButtonState, in other words it will be toggle-on-press instead of toggle-on-release.
I am trying to understand state machine in VHDL for detecting the edge on a signal in VHDL. in next state I dont understand why we put the:
"next_etat<= reg_etat" because I think it could work without any problem even without it .
I'd would what are the default value of reg_etat and next_etat when we have just run the program because their is no real default value like in c for example int var=0;
entity machine_etat is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
entree : in STD_LOGIC;
tc : out STD_LOGIC);
end machine_etat;
architecture architecture_machine_etat of machine_etat is
type T_etat is (idle,edge,one);
signal next_etat, reg_etat : T_etat;
begin
registre_etat: process(clk)
begin
if rising_edge(clk) then
if rst = ’1’ then
reg_etat <= idle;
else
reg_etat <= next_etat;
end if;
end if;
end process registre_etat;
tc <= ’1’ when reg_etat = edge else ’0’;
etat_suivant: process(reg_etat,entree)
begin
next_etat <= reg_etat;-- defaults values here i dont see their purpose
case reg_etat is
when idle =>
if entree =’1’ then
next_etat <= edge;
end if;
when edge =>
next_etat <= one;
when one =>
if entree =’0’ then
next_etat <= idle;
end if;
end case;
end process etat_suivant;
end architecture_machine_etat;
If you don't assign next_etat (pardon my French) in all situations, logical synthesis will infer a latch to remember it's state. A latch is something you don't want, as it is very sensitive to digital logic latencies and might become metastable: also something you don't want.
HDL programming significantly differs from CPU programming.
This has been driving me crazy. Here’s the code I have so far:
signal SYS_CLK : std_logic := '0'; --Input
signal InputSignal : std_logic := '0'; --Input
signal SyncOutputSignal : std_logic; --Output
------------------------------------------------------
stim_proc:process(SYS_CLK)
begin
if (rising_edge(SYS_CLK)) then
if (InputSignal = '1') then
assert (SyncOutputSignal = '0') report "Bad Pulse..." severity ERROR;
end if;
end if;
end process stim_proc;
And a picture of the ISim waveform ---> i.imgur.com/G5KvCQe.jpg
The purpose of this test is to confirm that when on rising_edge(SYS_CLK) if InputSignal = '1', then a pulse is emitted (SyncOutputSignal) equivalent and in line to SYS_CLK's period.
However, an Error report is being issued everytime the CLK goes high and InputSignal is High.
Long story short, I need a way to tell the program to wait for the next InputSignal Pulse before testing the assert statement listed in my code again. Any ideas??
It sounds like you are trying to check for an edge condition on InputSignal. When checking for an edge condition in hardware, there's a simple thing you can do. Create a registered version of InputSignal (I called it Reg_InputSignal). Then change your if statement to check for a 1 on InputSignal and a 0 on Reg_InputSignal. This is a rising edge condition on InputSignal and should only trip the if statement for 1 clock cycle.
architecture RTL of Entity_Name is
signal Reg_InputSignal : std_logic := '0';
begin
stim_proc : process(SYS_CLK)
begin
if (rising_edge(SYS_CLK)) then
Reg_InputSignal <= InputSignal;
if (InputSignal = '1' and Reg_InputSignal = '0') then
assert (SyncOutputSignal = '0') report "Bad Pulse..." severity error;
end if;
end if;
end process stim_proc;
I am fairly new to vhdl, I am working to understand if I can use it for a project.
I created a project to see how to implement pullup resisters and see how they work. I must have done something wrong.
My constraints entry for the wire is
net "rx_i" PULLUP;
net "rx_i" loc="p88";
the process for the project is
Process (clk_i)
type state_type is (qInit, qZero, qZero1, qZero2, qZero3, qZero4);
variable state: state_type:= qInit;
Begin
if (rising_edge(clk_i)) then
case state is
when qInit =>
if (rx_i = '0') then
led_o(0) <= '1';
state := qZero;
end if;
when qZero =>
if (rx_i = '0') then
led_o(1) <= '1';
state := qZero1;
end if;
when qZero1 =>
if (rx_i = '0') then
led_o(2) <= '1';
state := qZero2;
end if;
when qZero2 =>
if (rx_i = '0') then
led_o(3) <= '1';
state := qZero3;
end if;
when qZero3 =>
if (rx_i = '0') then
led_o(4) <= '1';
state := qZero4;
end if;
when qZero4 =>
if (rx_i = '0') then
led_o(5) <= '1';
state := qInit;
end if;
end case;
end if;
End Process;
All of the led's 0 thru 5 light up. If the wire is pulled up high I would expect maybe a few spurious 0's but not 6 in a row. Any help would be appreciated.
First: you never set the value of your leds back to '0'. Once you have set all values to '1' in this state machine, you keep driving '1'. You could add a line like led_o <= (others => '0'); before your case statement.
Even then, you will be running through the states at the speed of your clock. Your leds will be blinking so fast that your eyes just sees them as "on", but slightly less bright. perhaps you can add a counter in each state, or check for another condition like a button pushed.
Finally, the code you have posted shows nothing of a pull-up. I'm just assuming you are using that in another part of your code. The problems I can see have nothing to do with pull-ups.
Your constraints file is only used when the code gets synthesized and turned into a bitstream to be loaded onto the FPGA. It has nothing to do with simulation. In simulation you can create a pullup by driving 'H' (high) onto a signal.
If you want led_o to be the signal pulled up you could do:
led_o <= 'H';
led_o <= LED_DRIVE;
So when LED_DRIVE is high impedance (Z) then the pullup will take over and pull the signal high. This is how you would implement a bidirectional interface such as I2C. But I think now that I've gone over your head. The tutorial here shows how you could create a simple LED blinker: http://www.nandland.com/vhdl/tutorials/tutorial-your-first-vhdl-program-part1.html
This must be the most common problem among people new to VHDL, but I don't see what I'm doing wrong here! This seems to conform to all of the idioms that I've seen on proper state machine design. I'm compiling in Altera Quartus 9.2, for what it's worth. The actual error is:
"Can't infer register for "spiclk_out" at [file] [line] because it does not hold its value outside the clock edge"
ENTITY spi_state_machine IS
PORT(
spiclk_internal : IN STD_LOGIC;
reset : IN STD_LOGIC;
spiclk_out : BUFFER STD_LOGIC
);
END spi_state_machine;
PROCESS(spiclk_internal, reset)
BEGIN
IF reset = '1' THEN
spiclk_out <= '0';
END IF;
IF spiclk_internal = '1' AND spiclk_internal'EVENT THEN --error here
spiclk_out <= NOT spiclk_out;
END IF;
END PROCESS;
Thanks for your time.
As written, the process would cause spiclk_out to toggle on spiclk_internal edges even when reset is active, which is not how flip-flops with asynchronous resets should behave.
What you probably want is
SPICLK: process(spiclk_internal, reset)
if reset = '1' then
spiclk_out <= '0';
elsif spiclk_internal'event and spiclk_internal='1' then
spiclk_out <= not spiclk_out;
end if;
end process SPICLK;