Update data when clock goes low - VHDL - vhdl

I need to set output data when clock goes low and not to next rising_edge, I've modified a code to work in this way, but I've this warning:
Clock on register Empty tied to a constant
Clock on register Full tied to a constant
This is the code:
elsif rising_edge(Clock) then
if (Head = Tail) then
if Looped then
FullVar := '1';
else
EmptyVar := '1';
end if;
else
EmptyVar := '0';
FullVar := '0';
end if;
else
Full <= FullVar;
Empty <= EmptyVar;
end if;
end process;
To eliminate this warning I've modified code in this way:
elsif rising_edge(Clock) then
if (Head = Tail) then
if Looped then
FullVar := '1';
else
EmptyVar := '1';
end if;
else
EmptyVar := '0';
FullVar := '0';
end if;
end if;
Full <= FullVar;
Empty <= EmptyVar;
end process;
But when I compile code and simulate I've a higher delay before flag is asserted(in the corrected code without warnings). Why is that? Also, code works, but it's correct this type of code or data should be always updated when rising_edge?

Yes, you should always use rising_edge(Clock), unless you 'really' need a second clock domain. In your case you do not need a second clock domain.
There is also no reason to use variables in you example. The following code will raise Empty after a rising_edge of the clock, if Head is equal to Tail and Looped is '1' before the rising edge.
check : process (Clock)
if rising_edge(Clock) then
if Head = Tail then
if Looped then
Full <= '1';
else
Empty <= '1';
end if;
else
Empty <= '0';
Full <= '0';
end if;
end if;
end process;
If you want the have Empty raise before the rising edge you should do this combinatorially, like this:
check : process (Head,Tail,Looped)
Empty <= '0';
Full <= '0';
if Head = Tail then
if Looped then
Full <= '1';
else
Empty <= '1';
end if;
end process;
I hope this helps.

Related

Interfacing output to a DAC - VHDL

I am trying to interface the output of my FPGA onto a DAC. I am using the PmodDA2 DAC. The trouble I am having is working out how to output the data from a 16bit register into 1 bit per clock cycle.
I have studied the timing diagram and understand that CS needs to send a pulse before data transmission begins.
I have tried using the necessary resets and other features as applicable within my design as a whole.
I tried implementing a count to cycle between 0 to 16/17 and when it was at the beginning it would set CS to high and begin transmission. However I did not believe this would be at all the correct way to do it.
architecture Behavioral of DAC is
signal count : integer range 0 to 15;
signal selected : std_logic;
signal data_storage : std_logic_vector(15 downto 0);
begin
process(D_DAC, CE_DAC, RES_DAC, RES_DAC, data_storage)
begin
if RES_DAC = '1' then
data_storage <= "0000000000000000";
end if;
if rising_edge(CLK_DAC) then
if CE_DAC = '1' then
data_storage <= D_DAC;
end if;
end if;
end if;
end process ;
CS_DAC <= CE_DAC;
SCLK_DAC <= CLK_DAC;
DATA1_DAC <= data_storage;
end Behavioral;
I'm getting myself very confused over this.
I'd appreciate any help.
************************EDIT************************
I have had another go at implementing the counter...
process(D_DAC, CE_DAC, CLK_DAC, RES_DAC, data_storage)
begin
if RES_DAC = '1' then
data_storage <= "0000000000000000";
cound <= 0;
selected <= '0';
elsif rising_edge(CLK_DAC) then
if CE_DAC = '1' then
if count = 0 then
selected <= '1';
end if;
if selected = 1 then
if count = 15 then
count <= 0;
selected <= '0';
else
count <= count + 1;
data_storage <= D_DAC;
end if;
end if;
end if;
end if;
end process ;
CS_DAC <= CE_DAC;
SCLK_DAC <= CLK_DAC;
DATA1_DAC <= data_storage;
end Behavioral;

Generating 2 clock pulses in VHDL

How do I generate two clock pulses based on a trigger signal. I have found this code (which works very well) here in stackoverflow :
get_data:process(clk, reset)
variable idle : boolean;
begin
if reset = '1' then
idle := true;
elsif rising_edge(clk) then
clr_flag <= '0'; -- default action
if idle then
if flag = '1' then
clr_flag <= '1'; -- overrides default FOR THIS CYCLE ONLY
idle <= false;
end if;
else
if flag = '0' then
idle := true;
end if;
end if;
end if;
end process;
I was wondering if someone can help me in generating a flag that lasts 2 clock pulses instead of one.
I would just do this:
signal s_flag, s_flag_1z : std_logic := '0';
begin
get_data:process(clk, reset)
variable idle : boolean;
begin
if reset = '1' then
idle := true;
s_flag <= '0';
s_flag_1z <= '0';
elsif rising_edge(clk) then
s_flag <= '0'; -- default action
s_flag_1z <= s_flag;
if idle then
if flag = '1' then
s_flag <= '1'; -- overrides default FOR THIS CYCLE ONLY
idle <= false;
end if;
else
if flag = '0' then
idle := true;
end if;
end if;
end if;
end process;
cl_flag <= '1' when (s_flag & s_flag_1) /= "00" else '0';
Now the flag will be 2 clock cycles high and only a small addition was required.
/Ben
A variable length pulse is cleanest and easiest with a tap at the top of a shift register
get_data:process(clk, reset) --make sure you really want asynchronous reset
variable pulse_line : std_logic_vector(1 downto 0); --set the width to how many clocks you want the pulse
begin
if reset = '1' then --again make sure you really want asynchronous reset
pulse_line := (others => '1');
elsif rising_edge(clk) then
if flag = '1' then
pulse_line := (others => '1'); --reset the shift register
else
pulse_line := pulse_line(pulse_line'high-1 downto 0) & '0'; --push a 0 onto bottom of the shift register
end if;
clr_flag <= pulse_line(pulse_line'high); --tap out the top of the shift register
end if;
end process;

how to call a state machine from another state machine and get the response back in VHDL

I want to do VHDL programming of a state machine. In this state machine one state is itself another state machine. how can i call this state machine from the main state machine?
Example of what i actually want to do is as follows:
main state machine (sm_main.vhd) :-
clk_process : process (clk, reset)
begin
if(reset = '1') then
state_reg <= start;
elsif (clk'event and clk =' 1' ) then
state_reg <= state_next;
end if;
end process;
state_process : process (state_reg,input,enable)
begin
case state_reg is
when start =>
if (input =1) then
state_next <= wait;
else
state_next <= start;
end if;
when wait =>
if (enable =1) then
output <= '1';
state_next <= execute;
else
output <='0';
state_next <= wait;
end if ;
when execute =>
if (enable =1) then
state_next <= done;
else
state_next <= start;
end if;
when done =>
if(result = 1) then
state_next <= execute;
else
state_next <= start;
end if;
end case;
end process;
sub state machine (sm_execute.vhd):-
The execute state of the above state machine is itself another state machine program.
state_process : process (state_reg,a,b)
begin
case state_reg is
when start =>
if (a=1) then
state_next <= s1;
else
state_next <= s2;
end if;
when s1 =>
if (b =1) then
state_next <= s3;
else
state_next <= s3;
end if ;
when s3=>
if(c=1) then
result <= '1';
state_next <= s3
else
result <='0';
state_next <= start
end case;
end process;
What i want is to call this sm_execute.vhd in the execute state of sm_main.vhd. The output from the sm_execute which is result, is to be used as an input to determine the next state after execute in sm_main.vhd. That means i want to call the sub state machine program and also return the value to main state machine program once the sub state machine program finishes its execution.
thanks in advance
Sruthi Rajan
Handshaking. The first machine signals the second one to start, and waits for it to acknowledge. Then it retracts the start signal and waits for the second one to complete.
This is not the only way, but where you can separate the second state machine into its own process, it is probably the simplest.
First SM (master):
SM_1 : process(clock,reset)
begin
if reset = '1' then
State_1 <= Idle;
elsif rising_edge(clock) then
-- default actions
Start <= '0';
-- state machine proper
case State_1 is
...
when Need_Result =>
Start <= '1';
-- wait here until slave SM starts processing
if Done = '0' then
State_1 <= Wait_Result;
end if;
when Wait_Result =>
if Done = '1' then
State_1 <= Have_Result;
end if;
...
when others => State_1 <= Idle;
end case;
end if;
end process;
Second SM (slave) :
SM_2 : process(clock,reset)
begin
if reset = '1' then
State_2 <= Idle;
elsif rising_edge(clock) then
case State_2 is
when Idle =>
Done <= '1';
if Start = '1' then
Done <= '0';
State_2 <= Start_Process;
end if;
when Start_Process =>
State_2 <= Process_Done;
when Process_Done =>
Done <= '1';
if Start = '0' then
State_2 <= Idle;
end if;
when others => State_2 <= Idle;
end case;
end if;
end process;
Notice that in this implementation, the master waits for the slave to start processing (done = '0';). This covers cases where the slave may not be able to respond immediately. It does not cover cases where Done='0' already because the slave is processing data for another master.
Also the slave waits for the master to retract Start before returning to Idle. Usually Start will already be '0' but if it isn't, you probably don't want the slave to retrigger immediately.
If you can guarantee neither of these cases will happen you can simplify the handshaking a little, but the design becomes more sensitive to changes in signal timings.
Notice also that Start defaults to '0', because of the default assignment, but Done has no default assignment so it retains its state during processing. Unless you return to Idle (perhaps via an error path) when Done is set to indicate that processing has stopped.
If there is uncertainty about whether processing will complete, you may want the master to time out, rather than deadlock waiting for something that won't happen. I do this by adding a delay timer which can be used by different states for different purposes : here it detects a frozen slave and lets us handle the error.
First SM (master):
SM_1 : process(clock,reset)
variable Delay : natural range 0 to 100;
constant Timeout : natural := 50;
begin
if reset = '1' then
State_1 <= Idle;
Delay := 0;
elsif rising_edge(clock) then
-- default actions
Start <= '0';
if Delay > 0 then
Delay := Delay - 1;
end if;
-- state machine proper
case State_1 is
...
when Need_Result =>
Start <= '1';
-- wait here until slave SM starts processing
if Done = '0' then
Delay := Timeout;
State_1 <= Wait_Result;
end if;
when Wait_Result =>
if Done = '1' then
State_1 <= Have_Result;
elsif Delay = 0 then
State_1 <= Timed_Out; -- do error processing
end if;
...
when others => State_1 <= Idle;
end case;
end if;
end process;

Handling Interrupt in VHDL

We are using OR1200 for our project and we would like to assign an interrupt to the 8th button of FPGA Board. Here is the code to generate interrupt:
inrpt: process(CLK_I, RST_I)
begin
if RST_I = '1' then
butt_int_pul <= '0';
butt_int_tmp <= '0';
elsif rising_edge(CLK_I) then
if(DATA_I(8) = '1' and butt_int_tmp = '0') then
butt_int_pul <= '1';
else
butt_int_pul <= '0';
end if;
butt_int_tmp <= DATA_I(8);
end if;
end process inrpt;
process(CLK_I, RST_I)
begin
if RST_I = '1' then
butt_int <= '0';
elsif butt_int_pul = '1' then
butt_int <= '1';
elsif clear_int = '1' then
butt_int <= '0';
end if;
end process;
We only want this interrupt to be handled only once (holding the button should not call the interrupt again), that's why we included a flag to check this (butt_int_tmp).
The problem is that the interrupt call is not stable. It does not call each time we press the button. When we remove the flag, it works, but in this case, it is handled as many as we hold the button.
What are we doing wrong?
To start with, that second process is not properly written. It should have a structure equivalent to the first process (i.e., if(rising_edge(CLK_I)) surrounding all but the reset logic). You are currently describing a latch with multiple enable signals and wrong sensitivity list.
Moving on, there's no real reason you need that second process at all. You just need one register to act as interrupt (butt_int), and one to keep track of the previous state of the button (butt_prev). The interrupt is triggered for one cycle when DATA_I(8) is '1' while butt_prev is '0' (i.e., the button changed from not-pressed to pressed).
process(CLK_I, RST_I) begin
if(RST_I='1') then
butt_prev <= '0';
butt_int <= '0';
elsif(rising_edge(CLK_I)) then
if(DATA_I(8)='1' and butt_prev='0') then
butt_int <= '1';
else
butt_int <= '0';
end if;
butt_prev <= DATA_I(8);
end if;
end process;
Note that this will only work if your button is properly debounced, otherwise you are likely to get multiple interrupts triggered when you press (or even release) the button.
Its best not to think about interrupts. As you're targetting an FPGA, you're describing digital logic, not a software processor.
There a numerous way to build a circuit with the behaviour you want.
The simplest is probably a re-timed latch
signal latched_button : std_logic;
signal meta_chain : std_logic_vector(2 downto 0);
p_async_latch: process(rst_i,data(8))
begin
if rst_i = '1' then
latched_button <= '0';
elsif data(8) = '1' then
latched_button <= '1';
end if;
end process;
p_meta_chain: process(rst_i,clk_i)
begin
if rst_i = '1' then
meta_chain <= (others => '0');
elsif rising_edge(clk_i) then
meta_chain <= meta_chain(1 downto 0) & latched_button;
end if;
end process;
button_int <= '1' when meta_chain(2 downto 1) = "01" else '0';
This causes the button press to be latched asynchronously. The latched signal is then clocked along a shift register, and the interrupt is only valid for one cycle, which is the first clock cycle that the latch is seen on the clock domain.

Undesiderated 1-bit latch (VHDL)

I'm programming a N-bit non-restoring divider, but I faced a little problem.
I have an Operative Part (combinatorial) and a Control Part (Finite State Machine).
The Control Part has a 2 processes FSM, 1 for updating the next state and 1 for the "state sequence".
update: process(clk_in, next_state)
begin
if rising_edge(clk_in) then
current_state <= next_state;
end if;
end process;
And this is the second process:
control: process(current_state, start, S_in, counted)
variable sub_tmp : STD_LOGIC := '0';
begin
[...]
sub <= sub_tmp; -- sub is an output signal of my entity that goes in the Operative Part
case current_state is
when idle =>
if start='1' then
next_state <= init;
else
next_state <= idle;
end if;
when init =>
-- [...]
next_state <= subtract;
when subtract =>
en_A <= '1';
sub_tmp := '1';
next_state <= test;
when test => -- shift
en_Q <= '1';
if S_in='0' then
sub_tmp := '1';
else
sub_tmp := '0';
end if;
if counted=N/2-1 then
next_state <= finished;
else
next_state <= operation;
end if;
when operation =>
en_A <= '1';
next_state <= test;
when finished =>
stop <= '1';
next_state <= idle;
end case;
end process;
As you can see, I need to change the value of the sub ONLY in 2 cases (subtract and test), while I don't have to change in the other cases.
The problem is that when I try to synthesize this code it turns out that sub_tmp is a LATCH, but I don't want a latch.
I need to do something like this:
state 1 => set sub to '1' or '0' (depending on another input)
state 2 => do other operations (but sub must remain the value set before) and return to state 1
etc...
To clarify more: in certain states of my FSM (not all of them) I set the value of a variable (let's call it sub_tmp). In other states I don't change its value. Then let's say I have an output PIN called "sub_out". Now, independently of the variable value, I want to output its value to this pin (sub_out <= sub_tmp; or similar).
What am I missing?
What you are missing is the behavior you describe IS a latch. Anything with memory (ie: "in other states I don't change it's value") is either a latch or a register (flip-flop). If you don't want a latch or a register, you need to assign a specific value to the signal in each and every code path, and not let it 'remember' it's previous state.

Resources