1

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?

Bruno Kremel
  • 125
  • 3
  • 14
  • Is `delayedClock` your clock signal? If not (which I assume), how does it depend on your clock signal? If `delayedClock` is not a clock signal, your process is a combinational (in contrast to a sequential) process. – simon Apr 04 '13 at 13:42
  • It is 100kHz clock generated in my I2C module (this code is part of I2C module) from 150MHz clock, delayed by half period (difference between SCL and SDA). The issue with it is that I need to have it sensitive on both rising and falling edge of that delayedClock.. and therefore it infers combinatorial logic... – Bruno Kremel Apr 04 '13 at 13:47
  • What you want is unclear : you say "I want it to change output only when delayedClock changes it's state" but (a) on all state changes? (b) when other signals change while delayedClock high? or (c) only on rising_edge(delayedClock)? If (c) then at least you need to use the rising_edge function, but there is another problem : with clkEn false, there are unclocked activities which WILL NOT synthesise correctly. I would make `if Rising_edge(delayedClock) then ...` the outermost statement. –  Apr 04 '13 at 14:05
  • Brian: I thought that I can make process sensitve on both rising and falling edge exactly this way (that I don't specify rising/falling). I could get around by making delayedClock frequency double and having sensitivity on rising edge.. seems to me as kludge but I think it'll work.. I need this process act as (a) - all state changes of delayeClock (but not other signal).. For note.. in simulation it works as intended it evaluates process only when delayed clock is rising or falling. – Bruno Kremel Apr 04 '13 at 14:16
  • If the process outputs should be registers this is not possible (at least for the Spartan 6 architecture which has no double-edge sensitive flip-flops). If the process outputs are combinational - what is the point of having a signal that can change with 200MHz when your internal clock is only 100MHz? – simon Apr 04 '13 at 14:45
  • In fact even thought it's changing on both rising and falling edge it creates signal with 100kHz frequency... clkEn and sclIdleValue are only for creating I2C start and stop condition.. As I said it works in simulation but I couldn't figure out how to rewrite as it has the same behavior after synthesis.. – Bruno Kremel Apr 04 '13 at 14:52

1 Answers1

2

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: enter image description here

Bruno Kremel
  • 125
  • 3
  • 14