The NCO process

The corresponding waveforms

I have a very basic question here. When I learnt Processes it was said the statements occur sequentially.This is what I believed in. In the NCO process image file,there is proof for it. fword is assigned with a value and nco_acc is incremented in the next statement and in the third clk_pn is assigned. In the second image file,the corresponding synthesis results have been given. When reset goes low,fword gets its value in the first positive edge of the clock and in the next edge nco_acc is incremented and in the next edge clk_pn is assigned the msb of the nco_acc. Till here no problem. Then I met another problem.In the other image there is a process highlighted. here too there are two statements inside the process statement in the else part. But it happened concurrently. The statements occurred in the same clock cycle.

What should I conclude?

When is it sequential and when is it not?

            if (reset='1') then
            elsif (rising_edge(clk) ) then
            end if;
          end process NCO;

         if reset='0' or car_change = '1' then
            g2codereg <= "1111111111";
         elsif clk'event and clk='1' then
            g2codereg(1)           <= g2codereg(2) xor g2codereg(3) xor 
                                    g2codereg(6) xor g2codereg(8) xor 
                                g2codereg(9) xor g2codereg(10);
            g2codereg(10 downto 2) <= g2codereg(9 downto 1);
         end if;
       end process;
  • \$\begingroup\$ Can't you just copy and paste the relevant code directly into your question, rather than making us squint at tiny images? \$\endgroup\$ – Dave Tweed Jun 23 '15 at 16:26
  • \$\begingroup\$ Well I can't do that for the waveforms.I will try adding the code in the comment. \$\endgroup\$ – Muthu Subramanian Jun 23 '15 at 16:30

The statements inside a process are indeed executed sequentially, but they are all executed each time the process is activated (as defined by its sensitivity list).

Typically, the entire process will be executed once per clock edge, which means that any outputs (signals or variables) that get assigned within the process can all be updated on any given clock edge.

In this case, "sequential" refers to the relationships among the statements inside the process, but it has no bearing on its interaction with the rest of the design.

  • \$\begingroup\$ ALL can be updated in one clock edge? Is that what you meant? In that case my waveform results say otherwise. \$\endgroup\$ – Muthu Subramanian Jun 23 '15 at 16:33
  • 1
    \$\begingroup\$ I said that they can be, not that they will be. The latter depends on your specific code, which I didn't look at since you made it so difficult. \$\endgroup\$ – Dave Tweed Jun 23 '15 at 16:51
  • \$\begingroup\$ I get it now. The entire process acts on clock right? When a process is triggered due to signal change of one of the sensitivity signals in the sensitivity list,then the assignments occur all during the same clock keeping the value obtained at the moment of trigger. in that case even if I change the order of the assignment statements the output would be same. Right @Dave ? This explains why both the codes worked. \$\endgroup\$ – Muthu Subramanian Jun 23 '15 at 17:00
  • \$\begingroup\$ What do you think? @Dave? about my last comment? \$\endgroup\$ – Muthu Subramanian Jun 23 '15 at 18:17
  • \$\begingroup\$ Yes, when the clock edge occurs the assignments to each signal are made at the same time. In hardware this is usually implemented by a D-type flip-flop. The value which will be loaded on the edge is based on the combinatorial logic inferred from the right hand of the statement with the values latched by the flip-flops at the last clock edge. \$\endgroup\$ – Xcodo Jun 23 '15 at 18:22

The issue isn't with sequential statements, it's more fundamental having to do with signals.

No signal update takes effect while any process hasn't yet been suspended in the current simulation cycle. Signal driver updates are scheduled in projected output waveform queues. A signal retains it's value throughout the entire current simulation cycle which lasts until every process excited by an event on a signal it is sensitive to suspends.

This signal update:

    fword <= fword1(conv_integer(outp_sm)); 

is not available to the following sequential statement:

    nco_acc <= nco_acc+fword; 

until after the next event allowing execution of the enclosing process if statement (on the next rising clock edge).

Your other consecutive uses are similarly effected. Intermediary values should use variables or involve concurrent signal assignment.

Using intermediary variables would look something like this:

    process (clk, reset)
        variable fword_var:    std_logic_vector(fword'range);
        variable nco_acc_var:  std_logic_vector(nco_acc'range);
        if reset = '1' then
            clk_pn <= '0';
            nco_acc_var := (others => '0');
            fword_var := (others => '0');
        elsif rising_edge(clk)  then
            fword_var := fword1(conv_integer(outp_sm));
            nco_acc_var := nco_acc + fword_var;
            clk_pn <= nco_acc_var(nco_pngen_res - 1);
        end if;
        fword <= fword_var;
        nco_acc <= nco_acc_var;
    end process;

A fix using concurrent signal assignment would likely provide intermediary signals as input to signal assignments in the process.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.