HDL sythesis complains about missing signals in sensitivity list - vhdl

Hello I've got this simple VHDL process (Generated from MyHDL code):
DIGIPOT_CONTROLLER_CONNECTCLOCK: process (delayedClock) is
begin
if to_boolean(clkEn) then
if to_boolean(delayedClock) then
scl_d <= '0';
else
scl_d <= 'Z';
end if;
else
if to_boolean(sclIdleValue) then
scl_d <= 'Z';
else
scl_d <= '0';
end if;
end if;
end process DIGIPOT_CONTROLLER_CONNECTCLOCK;
Original MyHDL code:
#always(delayedClock)
def connectClock():
if(clkEn):
if(delayedClock):
scl_d.next = False
else:
scl_d.next = None
else:
if(sclIdleValue):
scl_d.next = None
else:
scl_d.next = False
In simulation it works perfectly(both ISIM and MyHDL simulator), but when I try to synthesise it into Spartan 6 it gives these warnings:
clken should be on the sensitivity list of the process
sclidlevalue should be on the sensitivity list of the process
Which I understand that it somehow inferred that this process should be sensitive on clkEn and sclIdleValue signals. But of course this is not what I have intended.
I want it to change output only when delayedClock changes it's state, not when clkEn or sclIdleValue changes their respective states.
Is it something that could not be done in Spartan 6 architecture? Or should I decribe process otherwise to have my intended behavior?

I have finally figured it out this is resulting MyHDL code:
#always(delayedClock.posedge, reset.posedge)
def connectClock():
if(reset == 1):
delayedClock_int.next = True
else:
delayedClock_int.next = not delayedClock_int
if(clkEn):
if(delayedClock_int):
scl_d.next = False
else:
scl_d.next = None
else:
if(sclIdleValue):
scl_d.next = None
else:
scl_d.next = False
and (generated) VHDL:
DIGIPOT_CONTROLLER_CONNECTCLOCK: process (delayedClock, reset) is
begin
if (reset = '1') then
delayedClock_int <= '1';
elsif rising_edge(delayedClock) then
delayedClock_int <= to_std_logic((not to_boolean(delayedClock_int)));
if to_boolean(clkEn) then
if to_boolean(delayedClock_int) then
scl_d <= '0';
else
scl_d <= 'Z';
end if;
else
if to_boolean(sclIdleValue) then
scl_d <= 'Z';
else
scl_d <= '0';
end if;
end if;
end if;
end process DIGIPOT_CONTROLLER_CONNECTCLOCK;
I had to make delayed clock twice the frequency (and then divide it by two in my connectClock process), this way it produces the same result as original process and it is sythesisable without warning.. the reason for phased out clock is SCL of I2C waveform as shown here:

Related

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.

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;

get vpos and hpos out vsync and hsync

For a project i got a screen with a resolution of 1024*600. For the project i need a squarre of 20px *20px with a red color. Im trying to get my verticale pos en horizontale pos out of the hsync en vsync pulse but this doesn't work. Have anyone a solution?
process(int_hsync, int_vsync)
begin
if Rising_Edge(int_vsync) then
vsync <= 0;
elsif Rising_Edge(in_clk) then
vsync <= vsync+1;
end if;
if Rising_Edge(int_hsync) then
hsync <= 0;
elsif Rising_Edge(in_clk) then
hsync <= hsync+1;
end if;
end process;
process(in_clk)
begin
if Rising_Edge(in_clk) then
if hsync < 20 and vsync <20 then
int_pixel <= X"0000ff";
else
int_pixel <= X"ff0000";
end if;
end if;
end process;
Without some additional details it is very difficult to tell what you are trying to do.
However, I did notice that your process is only sensitive to int_hsync and int_vsync, yet you are looking for a rising_edge of in_clk. You should do an edge detect similar to this, instead (assuming that in_clk is much faster than hsync and vsync):
process(in_clk)
begin
if rising_edge(in_clk) then
int_vsync_dly <= int_vsync;
int_hsync_dly <= int_hsync;
if int_vsync = '1' and int_vsync_dly = '0' then -- rising edge detect
vsync <= 0;
else
vsync <= vsync+1;
end if;
if int_hsync = '1' and int_hsync_dly = '0' then -- rising edge detect
hsync <= 0;
else
hsync <= hsync+1;
end if;
end if;
end process;
This increments vsync and hsync counters every time a rising edge of the respective trigger signals is observed. Do make sure that the inputs are properly registered before the edge detection to help avoid meta-stable cases.

Update data when clock goes low - 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.

Simplifying A State Machine To Reduce Logic Levels and Meet Timing

My design at the moment isn't meeting timing. I've tried putting it on a slower clock and pipelining the inputs/outputs. The problem is always the same - too many levels of logic. Have any of you got any tips on making this logic more clock friendly?
signal ctr : std_logic_vector(9 downto 0);
signal sig_bit_shift : std_logic_vector (15 downto 0);
begin
process(clk_p)
begin
if rising_edge(clk_p) then
if rst_i = '1' or nuke = '1' then
ctr <= (others => '0');
state <= ST_IDLE;
elsif unsigned(event_settings) < 1 then -- disables
state <= ST_IDLE;
elsif unsigned(event_settings) = 1 then -- always on
state <= ST_ENABLE;
else
case state is
when ST_IDLE =>
if ctr = (unsigned(event)-2) then
state <= ST_ENABLE;
elsif unsigned(ctr) = 1 and sig = '0' then --catches first word
state <= ST_ENABLE;
elsif sig = '1' then
ctr <= ctr + 1;
end if;
when ST_ENABLE =>
if s_sig = '1' then
state <= ST_IDLE;
if unsigned(s_evt) > 1 then
ctr <= (others => '0');
end if;
end if;
end case;
end if;
end if;
end process;
UPDATE:
process(clk_p)
begin
if rising_edge(clk_p) then
if rst_i = '1' or nuke = '1' then
ctr <= x"00" & "10";
state <= ST_IDLE;
elsif settings = '1' then
case state is
when ST_IDLE =>
if ctr = (unsigned(event)) then
state <= ST_ENABLE;
elsif unsigned(ctr) = 1 and sig = '0' then --catches first word -- this is the part which when added, fails timing
state <= ST_ENABLE;
elsif sig = '1' then
ctr <= ctr + 1;
end if;
when ST_ENABLE =>
if s_sig = '1' then
state <= ST_IDLE;
if unsigned(s_evt) > 1 then
ctr <= X"00" & "10";
end if;
end if;
end case;
end if;
end if;
end process;
I think too it's slowed down by where the signal comes from:
sig <= sig_token when unsigned(SIG_DELAY) < 1 else (sig_bit_shift(to_integer(unsigned(SIG_DELAY)-1)));
process(clk_p) -- delays sig
begin
if rising_edge(clk_p) then
if rst = '1' then
sig_bit_shift <= (others => '0');
else
sig_bit_shift <= l1a_bit_shift(sig_bit_shift'high-1 downto 0) & sig_token;
end if;
end if;
end process;
UPDATE 2 :
Seems like half the routing went into the above delay so i'm going to try and fix with this:
signal sig_del_en : std_logic;
signal sig_del_sel : integer;
begin
process(clk_p)
begin
if rising_edge(clk_p) then
if unsigned(SIG_DELAY) = 0 then
sig_del_en <= '0';
else
sig_del_en <= '1';
end if;
sig_del_sel <= to_integer(unsigned(SIG_DELAY)-1);
end if;
end process;
sig <= sig_token when sig_del_en = '0' else (sig_bit_shift(sig_del_sel));
Some of the "slow" operations are array = which requires compare over all bits in the argument, and < and > which requires subtraction over all bits in the argument. So you may improve timing in a cycle, if there is sufficient time in the previous cycle to generate the compare result up front as a std_logic. It may be relevant for these:
unsigned(event_settings) < 1
unsigned(event_settings) = 1
ctr = (unsigned(event)-2)
unsigned(ctr) = 1
unsigned(s_evt) > 1
The code to generate the different std_logic values depends on the way the related signal is generated, but an example can be:
process (clk) is
variable event_settings_v : event_settings'range;
begin
if rising_edge(clk) then
...
event_settings_v := ... code for generating event_settings; -- Variable with value
event_settings <= event_settings_v; -- Signal drive from variable
if unsigned(event_settings_v) < 1 then
unsigned_event_settings_tl_1 <= '1';
else
unsigned_event_settings_tl_1 <= '0';
end if;
end if;
end process;
The code unsigned(event_settings) < 1 in the state machine can then be changed to unsigned_event_settings_tl_1 = '1', which may improve timing if this compare is in the critical path.
Using the asynchronous reset typically available on the the flip-flop for rst_i = '1' may also improve timing, since it removes logic from the synchronous part. It is unlikely to give a significant improvement, but it's typically a good design practice in order to maximize the time for synchronous logic. The asynchronous reset is used through coding style like:
process (rst_i, clk_p) is
begin
if rst_i = '1' then
... Apply asynchronous reset value to signals
elsif rising_edge(clk_p) then
... Synchronous update of signals

Resources