0

I want to generate a test stimulus for my I2S demux module. The stimulus contains values from an ADC measurement. The I2S standard provides two clocks: LRCLOCK and BITCLOCK. In my case LRCLOCK has a frequency of 48kHz (which is also the sample rate) and BITCLOCK is 64*LRCLOCK which results in a clock of 3.072MHz.

When creating the clocks in the testbench, there is always a offset between the LRCLOCK and the BITLCOCK. And I can't explain where this offset is coming from.

I tried to create a clock generation procedure according to this post: VHDL - How should I create a clock in a testbench?

Both suggested solutions show the same behaviour. I work with VIVADO 2016.4, the simulator has a resolution of 1ps

Procedure:

procedure clk_gen(signal clk : out std_logic; constant FREQ : real) is
    constant PERIOD    : time := 1 sec / FREQ;        -- Full period
    constant HIGH_TIME : time := PERIOD / 2;          -- High time
    constant LOW_TIME  : time := PERIOD - HIGH_TIME;  -- Low time; always >= HIGH_TIME
  begin
    -- Check the arguments
    assert (HIGH_TIME /= 0 fs) report "clk_plain: High time is zero; time resolution to large for frequency" severity FAILURE;
    -- Generate a clock cycle
    loop
      clk <= '1';
      wait for HIGH_TIME;
      clk <= '0';
      wait for LOW_TIME;
    end loop;
  end procedure;

Clock assignment:

process
    begin
        i2s_lrclock <= '1';
        wait until reset /= '1';
        clk_gen(i2s_lrclock,48.0e3);
   end process;

 process
   begin
       i2s_bitclock <= '1';
       wait until reset /= '1';
       clk_gen(i2s_bitclock,48.0e3*64);
  end process;

I expect the edges of both clocks to be synchronous but there is an offset of 26ps from the i2s_bitclock to i2s_lrclock.

le_audio
  • 13
  • 4
  • 1
    Whose simulator implicitly converts an integer abstract literal into a floating point type, or did you mean 64.0 in the second process? Type REAL is an approximation of real numbers, limited by mantissa accuracy. Derive one clock from the other, don't mess around with REALs. –  May 24 '19 at 11:29
  • Thank you for the hint. The simulator did not complain about that. I used the solution suggested below and it works now. – le_audio May 25 '19 at 20:03
  • The accepted answer doesn't reflect how clocks are related in hardware. The expectation a simulator would report an error for an unspecified and untested relationship between the two clocks isn't realistic. There's an underlying assumption you're aware of REAL semantics, particularly the 'approximation' bit. –  May 25 '19 at 21:50

1 Answers1

0

A 3.072MHz clock has a period of 325.5208333... ns, the simulator has to trunk the period somewhere, and it's probably not on the same digit for your other clock.

Try something like that :

signal i2s_lrclock   : std_logic := '0';
signal i2s_bitclock  : std_logic := '0';

begin

  i2s_lrclock   <= not(i2s_lrclock) after 10416640 ps;  -- 64 * 325.520 ns / 2
  i2s_bitclock  <= not(i2s_bitclock) after 162760 ps ;  -- 325.520 ns / 2

Real value of clocks in simulation is not very important. Ratio between them is.

Gautitho
  • 591
  • 2
  • 5
  • 13