Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

New to VHDL: Understanding timer.vhd implementation

I'm an old hand at C/C++ just getting my feet wet with VHDL. In the course of my learning, I've used the SOPC builder to create a simplified system that included a timer. Part of the emitted VHDL code for the timer includes the following snippet:


  control_wr_strobe <= (chipselect AND NOT write_n) AND to_std_logic((((std_logic_vector'("00000000000000000000000000000") & (address)) = std_logic_vector'("00000000000000000000000000000001"))));
  process (clk, reset_n)
  begin
    if reset_n = '0' then
      control_register <= std_logic'('0');
    elsif clk'event and clk = '1' then
      if std_logic'(control_wr_strobe) = '1' then 
        control_register <= writedata(0);
      end if;
    end if;
  end process;
In simulating this with ModelSim and 'manually' driving chipselect, write_n, etc., it appears that the write into the control register by writedata(0) does not occur unless I extend the assertions of the signal lines (chipselect, write_n, address) so they last for at least two rising edges of 'clk'.

My understanding is that because all of this is concurrent, on the first iteration (assuming the chipselect, write_n get asserted with the rising edge of 'clk'), ModelSim will not evaluate the "if std_logic'(control_wr_strobe) = '1' then" statement to true.. at least not on the first 'delta' iteration. This is because all of the processes and the implied process driving the value to control_wr_strobe occur at the same time. It won't be until after the delta time in the simulation following the rising edge event that control_wr_strobe will be actually evaluated to a '1'. By this time, it's too late - the rising clock edge has been evaluated and will not cause the process(clk,reset_n) to be scheduled again. Instead, it's necessary to keep chipselect & write_n asserted so that on the *next* rising clk edge the control_register is updated.

Is this line of thought correct?

Further, this is looking at things from a simulation mindset. When things are synthesized, is this same timing required? In other words, the chipselect and write_n lines will need to be held for at least two clock cycles to be properly executed. Does this mean that the Avalon MM Slave interface requires at least 1 wait cycle for a write? I believe this is the case, but was hoping for confirmation.

Thanks!

--tim

7 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Your line of thought is quite correct. If you change the input signals at the same time as clk rising, that very rising edge of the clk sees the previous values and it is only at the next rising edge of clk that the input changes will be evaluated.

    I assume you are doing a functional simulation. In that case you could change the inputs at the falling edge of the clock (or at one quarter after the rising edge). Now the next rising edge will nicely evaluate all changes in one action.

    In real life your MM Slave will not require a wait-cycle, because the changes will be the effect of a (previously) rising clock edge.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I concur with josyb. It can be quite tricky at first trying to work out why a signal is changing on a clock but not acted upon until the next clock, which is why making inputs change on the falling edge can make thing a little clearer. This way they are only ever active for 1 clock edge, not 2 like you previously thought.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks for the response. I've got a follow-up question regarding the timer.vhd implementation.

    There is some code driven by an internal signal named "clk_en". At the beginning of the architecture, there's this:

    
    clk_en <= std_logic'('1');
    
    And then later on there's this:

    
      process (clk, reset_n)
      begin
        if reset_n = '0' then
          force_reload <= std_logic'('0');
        elsif clk'event and clk = '1' then
          if std_logic'(clk_en) = '1' then 
            force_reload <= period_h_wr_strobe OR period_l_wr_strobe;
          end if;
        end if;
      end process;
     
    What is the purpose of checking clk_en? I'm guessing it's primarily for simulation purposes as a guard in the event that there is an immediate rising edge to prevent (in this case) force_reload from being updated with data that may not yet have a defined value. Is this the case?

    Thanks,

    --tim
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I doubt it. Im guessing it was either intended to be upgraded to a real clock enable, or it was once a clock enable and found it easier to force it to one rather than removing the code the process.

    I have a question for you - where are there unnessasary std_logic qualifications all over the code?

    clk_en <= '1'; is perfectly acceptable. You only need std_logic'() when you need to qualify something is a std_logic rather than a bit or a character. When a signal is already defined as a std_logic, there is no need to qualify its assignment. std_logic'(signal) is even more unnessasary - the signal is already a std_logic.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The code snippets I've been listing are from the VHDL code that was emitted (automatically generated) as a result of including a timer using the SOPC builder. In other words, I'm including it from Library > Peripherals > Microcontroller Peripherals > Interval Timer, generating the system, and then looking at the result as a point of reference as I delve into VHDL.

    It's *that* code that is including the extra std_logic'() stuff as well as including what looks like the vacuous use of an internal signal (clk_en).

    --tim
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    as its generated code, it is following a given template. There is nothing wrong with the code. generated code can often look at bit odd

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Understandable. I was just answering your question about why std_logic'() was being used all over the place...

    I also wanted to make sure there wasn't anything I wasn't "getting" with respect to clk_en usage.

    Thanks for all the help!

    --tim