Signal becomes 0X00 from 0100 - vhdl

I am working on a Program Counter that must be added 4 in each rising edge of a clk:
Code:
if_CounterSum <= MemAddr + 4;
process (Clk, Reset)
begin
if Reset = '1' then
MemAddr <= (OTHERS => '0');
elsif rising_edge(Clk) then
MemAddr <= if_CounterSum;
end if;
end process;
When simulating in ISIM,
After Reset is set to 0:
Initial state:
MemAddr = 0 (0000)
if_CounterSum = 4 (0100)
First CLK rising_edge:
MemAddr = X (0X00)
if_CounterSum = X (XXXX)
I have been working on this "simple" thing for some hours, I have tried:
Change the +4 line to synchronous too (Into the process) but problem kept.
Some other stuff that didn't worked.
How can I fix that X? I have tested other numbers instead of 4 and as I guessed all '1's in if_CounterSim where converted in 'X's after the assignment.

You have not included all of the code, so below is a guess.
The problem is probably a result of VHLD resolution of the signal, whereby multiple conflicting drivers of the same signals as for example both '0' and '1' will result in 'X', but where two drivers of '0' will result in '0'.
So look for all places in the module where MemAddr and if_CounterSum are assigned, and remove those unnecessary assigns.

When assigning a signal outside a process you literally connect it to the right side of the arrow.
When assigning a signal inside a synchronous process you implement flip flops to assign a value to your signal on clock edges.
In your case, I suggest you put if_CounterSum <= MemAddr + 4; in your process. This way, the increment will be done at each clock rising edge.
process (Clk, Reset)
begin
if Reset = '1' then
MemAddr <= (OTHERS => '0');
elsif rising_edge(Clk) then
MemAddr <= MemAddr + 4;
end if;
end process;
If you really need the if_CounterSum you can add if_CounterSum <= MemAddr outside the process this time (because it would be wired).

Related

How do I correctly implement a Finite-State Machine into VHDL without taking in multiple inputs from Basysy3 FPGA

I am new to VHDL and I am attempting to implement the following state machine into VHDL (state diagram provided below). When I press a button on my Basys3 FPGA board( P input) the output is a random state. I suspect this is because the clock is going through many cycles during a single press so more than 1 input is being taken in from a single press but I am unsure. Is there anything I can do to fix this. I want to be able to press button P and the states change one at a time.
library IEEE;
USE ieee.std_logic_1164.all;
ENTITY trasher is
PORT (
clock : IN STD_LOGIC;
P : IN STD_LOGIC;
reset : IN STD_LOGIC;
LED3, LED1,LED2,LED0 : OUT STD_LOGIC);
END ENTITY;
-- Architecture definition for the SimpleFSM entity
Architecture RTL of trasher is
TYPE State_type IS (A, B, C, D); -- Define the states
SIGNAL State : State_Type; -- Create a signal that uses
-- the different states
BEGIN
PROCESS (clock, reset)
BEGIN
IF (reset = '1') THEN -- upon reset, set the state to A
State <= A;
ELSIF rising_edge(clock) THEN -- if there is a rising edge of the
-- clock, then do the stuff below
-- The CASE statement checks the value of the State variable,
-- and based on the value and any other control signals, changes
-- to a new state.
CASE State IS
-- If the current state is A and P is set to 1, then the
-- next state is B
WHEN A =>
IF P='1' THEN
State <= B;
END IF;
-- If the current state is B and P is set to 1, then the
-- next state is C
WHEN B =>
IF P='1' THEN
State <= C;
END IF;
-- If the current state is C and P is set to 1, then the
-- next state is D
WHEN C =>
IF P='1' THEN
State <= D;
END IF;
-- If the current state is D and P is set to 1, then the
-- next state is B.
-- If the current state is D and P is set to 0, then the
-- next state is A.
WHEN D=>
IF P='1' THEN
State <= B;
ELSE
State <= A;
END IF;
WHEN others =>
State <= A;
END CASE;
END IF;
END PROCESS;
-- Decode the current state to create the output
-- if the current state is D, R is 1 otherwise R is 0
LED0 <= '1' WHEN State=A ELSE '0';
LED1 <= '1' WHEN State=B ELSE '0';
LED2 <= '1' WHEN State=C ELSE '0';
LED3 <= '1' WHEN State=D ELSE '0';
END rtl;
Do not use directly the input from your press-button. What you need to feed your state machine is the output of a rising edge detector of P, not P itself.
Moreover P is not synchronous with your master clock and there is thus a risk of meta-stability. Last but not least, if it bounces, you will get several value changes instead of just one. To solve the meta-stability issue you need a re-synchronizer, which is just a shift register. And you can also use it to generate an intermediate signal that is asserted high during only one clock period when the button is pressed, that is, the rising edge detector you need for your state machine. Example with 3-stages:
signal sync: std_ulogic_vector(0 to 2);
signal button_pressed: std_ulogic;
...
process(clock, reset)
begin
if reset = '1' then
sync <= (others => '0');
elsif rising_edge(clock) then
sync <= P & sync(0 to 1);
end if;
end process;
button_pressed <= sync(1) and (not sync(2));
Stages 1 and 2 of sync are safe to use because they have already been resynchronized (assuming 2 stages are enough for your target technology and mean time between failures; read something about meta-stability, maybe, if you don't understand this).
When the button is pressed, ones are shifted in sync. After two clock periods sync = "110" so button_pressed is asserted high. One clock period later sync = "111" and button_pressed is de-asserted. button_pressed is thus a one-clock-period-only indicator that the button was pressed. You can use it as an input of your state machine.
The second problem comes from the way press-buttons work. If your prototyping board does not already debounce its press-buttons it can be that, when the button is pressed, your P input oscillates several times between 0 and 1 before stabilizing to 1. Same when the button is released. As this is sometimes not the case do some tests before implementing a debouncer. For instance, count the number of times button_pressed is asserted high and send this to your LEDs:
signal cnt: u_unsigned(3 downto 0);
...
process(clock, reset)
begin
if reset = '1' then
cnt <= (others => '0');
elsif rising_edge(clock) then
cnt <= cnt + button_pressed;
end if;
end process;
LED0 <= std_logic(cnt(0));
LED1 <= std_logic(cnt(1));
LED2 <= std_logic(cnt(2));
LED3 <= std_logic(cnt(3));
If your button bounces you should sometimes see more than one increment when you press it. It will be time to search a bit about debouncing and, if needed, to ask a new question.

VHDL - Inferred Latch With Reset - FSM

I have an issue with this process where if I include a reset statement, I get an inferred latch. However, if I do not include the reset statement, I do not get an inferred latch on duty_cycle_triangle.
SIGNAL duty_cycle_triangle : INTEGER := 0;
SIGNAL count_up : STD_LOGIC;
SIGNAL tick_zero : STD_LOGIC;
triangle_count: PROCESS(clk, reset signal, tick_zero)
BEGIN
IF (reset = '1') THEN
duty_cycle_triangle <= 0;
ELSIF (RISING_EDGE(clk)) THEN
IF (tick_zero = '1') THEN
IF (count_up = '1') THEN
duty_cycle_triangle <= duty_cycle_triangle + 2;
ELSE
duty_cycle_triangle <= duty_cycle_triangle - 2;
END IF;
END IF;
END IF;
END PROCESS;
I am trying to design an FSM that will output a triangle wave using a PWM and an FSM shown below:
FSM_comb: PROCESS(currentState, duty_cycle_triangle)
BEGIN
CASE currentState IS
WHEN triangle_up =>
PWM_enable <= '1';
count_up <= '1';
IF (duty_cycle_triangle > 99) THEN
nextState <= triangle_down;
ELSE
nextState <= triangle_up;
END IF;
WHEN triangle_down =>
PWM_enable <= '1';
count_up <= '0';
IF (duty_cycle_triangle < 1) THEN
nextState <= triangle_up;
ELSE
nextState <= triangle_down;
END IF;
END CASE;
END PROCESS;
FSM_seq: PROCESS(clk, reset)
BEGIN
IF (reset = '1') THEN
currentState <= triangle_up;
ELSIF (RISING_EDGE(clk)) THEN
currentState <= nextState;
END IF;
END PROCESS FSM_seq;
Basically, after every "tick" I want the duty cycle of the triangle wave to increase by 2. After the duty cycle reaches 100, I want the duty cycle to decrease by 2 until the duty cycle reaches 0. Once the duty cycle reaches 0, I want the duty cycle to start increasing from 0 again until it reaches 100 and it starts over.
Does anyone see any problems with my code or can anyone point me in the right direction to correcting any issues?
If you want to create a sequential process, only include a reset and a clock in your sensitivity list. I suspect that it's inferring the latch because you're including too many signals in this process:
triangle_count: PROCESS(clk, reset signal, tick_zero)
It should just be
triangle_count: PROCESS(reset, clk)
The tools don't see that as a sequential process and make it combinational and that's how you get your latch.
Without trying it out i'm wondering if when the reset statement is removed, the tool is recognising the process as a synchronous process and inferring registers. In this case you don't need to explicitly define duty_cycle_triangle for each outcome of the process as the value is stored in a register.
With the reset statement included it may be treating the process as combinatorial and therefore inferring latches to store the state of duty_cycle_triangle when it's not explicitly defined.
Either way I agree with Russell's suggestion of changing the process sensitivity list which should get rid of the latch.

Blocking Assignments on SIGNALS in VHDL

I am making an FSM with VHDL. The simplest possible when valid = 1 change from stateA to stateB.
The confusing part is the rising edge selected by the blue rectangular. When valid = '1'. At the first rising edge, the state will be calculated to be B but it won't take effect until the next rising edge BUT what happened that it took effect at the FIRST rising edge.
Because the change in the state from A to B should affect other parts ( parallel process ) in the design in the NEXT cycle. From the waveform, If valid = '1' just before CLK_1.
At, CLK_1 all other processes should see state = A | waveform correct
output
state = A
enteredlastcycle = 0
At, CLK_2 all processes start seeing state = B. another parallel
process checks if state = B then it drives ENTERED_STATEB_LASTCYCLE to
be 1 waveform correct output
state = B
enteredlastcycle = 0
Then at CLK_3, waveform correct output
state = B
enteredlastcycle = 1
Do I misunderstand something?
Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.KDlib.all;
entity nearestPoint is
generic ( ARRAY_WIDTH : integer := 8);
port (
clk: in std_logic;
reset: in std_logic;
inpoint: in kdvector;
valid: in std_logic;
finished: buffer std_logic
);
end nearestPoint;
architecture behave of nearestPoint is
signal state: two_state_type;
signal stateB_entered_lastCycle: std_logic;
begin
process ( clk )
begin
if ( reset = '1' ) then
elsif ( rising_edge(clk) ) then
case state is
when stateA =>
if ( valid = '1' ) then
state <= stateB;
end if;
when stateB =>
when others =>
end case;
end if;
end process;
process(clk)
begin
if ( reset = '1' ) then
elsif ( clk = '1' ) then
case state is
when stateA =>
when stateB =>
stateB_entered_lastCycle <= '1';
when others =>
end case;
end if;
end process;
end behave;
I will give you an explanation through a digital circuit prism. It is a way of thinking that you have to keep in mind when you develop VHDL.
Your valid is at 1 before the clock edge. You are in simulation so you can imagine that all your computations are instant. At the input of your flipflop the new value of your state is already calculated.
I am used to code with only one sequential process and one or more combinational process. Maybe you will understand better with this code with same functionnality than yours (a bit simplified) :
SEQ : process(clk, rst)
begin
if rst = '1' then
current_state <= '0';
elsif rising_edge(clk) then
current_state <= next_state;
end if;
end process SEQ;
Circuit corresponding to this code :
COMB : process(current_state, valid)
begin
next_state <= current_state; -- Default value to ensure that next_state will always be affected
if current_state = '0' and valid = '1' then
next_state <= '1';
end if;
end process COMB;
Circuit correspondint to this code :
If we consider that when valid changes next_state is refreshed instant, current_state (state in your code) goes high on the very next clock rising edge.
Hope you will understand, if you need more precision, don't hesitate to ask, I can edit my post or answer in comments.
Important note : If you have an asynchronous reset in your sequential process, it has to be in sensitivity list.
VHDL has no concept of blocking/non-blocking assignments. There are signals and variables and they are assigned differently.
In your case, you need to remember that simulation runs on a series of delta cycles. 1 delta is an infinitely small space of time, but they happen sequentially. A signal assignment doesn't take effect until the end of the delta, so state = B in the delta cycle after the rising edge of the clock. The 2nd process is sensitive only the clock, so it cannot update stateB_entered_lastcycle until the clock rises again.

Is the use of rising_edge on non-clock signal bad practice? Are there alternatives?

I am working on a VHDL design and I have it working, but the code is pretty ugly and the fact that it seems that I am trying to work around the language's design to accomplish my goal makes me feel like something is wrong. I'm pretty new to VHDL, but I have been working on smaller chunks of the project for nearly a month so I have the general idea. However, This part is a bit more complex.
I need a process that will create a one clock period long pulse (LOAD_PULSE) after the rising edge of a signal (END_ADC), but not until 4 clocks has passed from the latest rising edge of that signal (END_ADC) OR the falling edge of a second signal (LVAL).
To accomplish the wait period, I have built a timer module that counts microseconds and periods, here:
entity uS_generator is
generic(
Frequency : integer := 66 -- Frequency in MHz
);
Port (
CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
T_CNT : out integer range Frequency downto 1 := 1;
uS_CNT : out integer range 65535 downto 0 := 0
);
end uS_generator;
architecture behavior of uS_generator is
signal T_CNT_INT : integer range Frequency downto 1 := 1; -- Counter for 1 uS
signal uS_CNT_INT : integer range 65535 downto 0 := 0;
begin
COUNT: process(CLK, RESET)
begin
if RESET = '1' then
T_CNT_INT <= 1;
uS_CNT_INT <= 0;
elsif rising_edge(CLK) then
if T_CNT_INT = (Frequency - 1) then -- Increment one clock early so last rising edge sees one uS elapsed.
uS_CNT_INT <= uS_CNT_INT + 1;
T_CNT_INT <= T_CNT_INT + 1;
if uS_CNT_INT = 65535 then
uS_CNT_INT <= 0;
end if;
elsif T_CNT_INT = Frequency then
T_CNT_INT <= 1;
else
T_CNT_INT <= T_CNT_INT + 1;
end if;
end if;
end process COUNT;
T_CNT <= T_CNT_INT;
uS_CNT <= uS_CNT_INT;
end behavior;
The processes I'm using for the pulse generation portion of the design are as follows:
loadPulseProc: process(PIXEL_CLK, END_ADC, RESET)
begin
if RESET = '1' then
PULSE_FLAG <= '0';
LOAD_PULSE <= '0';
elsif rising_edge(END_ADC) then
PULSE_FLAG <= '1';
end if;
if rising_edge(PIXEL_CLK) then
if PULSE_FLAG = '1' and END_ADC = '1' and LVAL <= '0' and ADC_TMR_T >= 4 and LVAL_TMR_T >= 4 then
LOAD_PULSE <= '1', '0' after PIXEL_CLK_T;
PULSE_FLAG <= '0';
end if;
end if;
end process loadPulseProc;
ADCTimerProc: process(END_ADC, RESET)
begin
if RESET = '1' then
ADC_TMR_RST <= '1', '0' after PIXEL_CLK_T/10;
end if;
if rising_edge(END_ADC) then
ADC_TMR_RST <= '1', '0' after PIXEL_CLK_T/10;
end if;
if falling_edge(END_ADC) then
ADC_TMR_RST <= '1', '0' after PIXEL_CLK_T/10;
end if;
end process ADCTimerProc;
LVALTimerProc: process(LVAL, RESET)
begin
if RESET = '1' then
LVAL_TMR_RST <= '1', '0' after PIXEL_CLK_T/10;
end if;
if rising_edge(LVAL) then
LVAL_TMR_RST <= '1', '0' after PIXEL_CLK_T/10;
end if;
if falling_edge(LVAL) then
LVAL_TMR_RST <= '1', '0' after PIXEL_CLK_T/10;
end if;
end process LVALTimerProc;
PIXEL_CLK_T is the period of the clock, 15.152 ns.
This design works, simulation shows that it does as I require, but only after significant hassle avoiding errors due to using multiple rising_edge of falling_edge calls by separating them into separate if statements that really should be together. As far as I've read using rising_edge and falling_edge seems to be reserved for clocks only, so is this just bad practice? How can avoid this behavior but still create the same output?
Thanks!
Yes, rising_edge()/falling_edge() should only be used for clock signal. While it works in simulation it can cause problems and unintended hardware in synthesis.
Synthesis tools infer a clock from the function's argument and place such signals/wires on special tracks in the FPGAs (assuming you are targeting an FPGA for your design). The tool will further infer special clock buffers and warn if your input clock pin is not a clock capable pin.
Introducing several clocks can lead to asynchronous designs and make it vulnerable for cross clock faults.
Detecting a rising or falling edge on a signal is done by an edge detection circuit like the following which compares the signal in the previous clock cycle to the current value.
Needed signals:
signal mySignal_d : std_logic := '0';
signal mySignal_re : std_logic;
Needed logic:
mySignal_d <= mySignal when rising_edge(Clock);
mySignal_re <= not mySignal_d and mySignal;
This first line translates to an 1-bit D-flipflop (You could also use a process). The second lines generates a one cycle strobe signal when mySignal changes from low to high. I'm using *_d to indicate a delayed signal of the original input and *_re for rising edge.
The generated signal is still synchronous to Clock.

Comparison with 0 or 1, to detect high impedence

I know that its not allowed to compare with X or Z in a synthesizable VHDL code. But is it allowed to write a code in which I compare a signal to 0 or 1 to detect an Z and suspend the operation? The code is as follows:
process(clk)
begin
if rising_edge(clk ) then
if(rst = '0') then
reg_0 <= (others => 'Z');
elsif(btf_start = '1') then
reg_0 <= "ZZ" & frame_in;
elsif(t_btf_finish = '1') then
reg_0 <= (others => 'Z');
end if;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
if(reg_0(0) = '0' or reg_0(0) = '1') then
-- DO SOME OPERATIONS
else
-- DO NOTHING
end if;
end if;
end process;
No, this won't work. Physical digital signals can have exactly 2 states, '0' and '1'. The states are defined by the voltage on the signal: less than some voltage is a '0', greater than that voltage is a '1'. Even floating (high-z) signals will have some voltage that will be interpreted as a '1' or '0'.
'Z' basically says that a certain source isn't driving the signal, allowing a different source to drive a '0' or '1'. For the case when no source is driving the signal, the signal will usually have a pull-up or pull-down resistor to keep it in a defined '1' or '0' state by default.

Resources