Continuous assignment seemingly not working

后端 未结 4 1125
北海茫月
北海茫月 2020-12-06 02:38

I\'m working on a FIR filter, specifically the delay line. x_delayed is initialized to all zeros.

type slv32_array is array(natural range <&g         


        
相关标签:
4条回答
  • 2020-12-06 03:01

    In the first case, the x_delayed(0) actually has two drivers, out outside the process, being x_delayed(0) <= x, and an implicit one inside the DELAY process.

    The driver inside the process is a consequence of a VHDL standard concept called "longest static prefix", described in VHDL-2002 standard (IEEE Std 1076-2002) section "6.1 Names", and the loop construction with a loop variable i, whereby the longest static prefix for x_delayed(i) is x_delayed.

    The VHDL standard then further describes drives for processes in section "12.6.1 Drivers", which says "... There is a single driver for a given scalar signal S in a process statement, provided that there is at least one signal assignment statement in that process statement and that the longest static prefix of the target signal of that signal assignment statement denotes S ...".

    So as a (probably surprising) consequence the x_delayed(0) has a driver in the DELAY process, which drives all std_logic elements to 'U' since unassigned, whereby the std_logic resolution function causes the resulting value to be 'U', no matter what value is driven by the external x_delayed(0) <= x.

    But in the case of your code, there seems to be more to it, since there actually are some "0" values in the simulation output for x_delayed(0), for what I can see from the figures. However, it is hard to dig further into this when I do not have the entire code.

    One way to see that the loop is the reason, is to manually roll out the loop by replacing the for ... loop with:

    x_delayed(1) <= x_delayed(1-1);
    x_delayed(2) <= x_delayed(2-1);
    ...
    x_delayed(NTAPS) <= x_delayed(NTAPS-1);
    

    This is of course not a usable solution for configurable modules with NTAPS as a generic, but it may be interesting to see that the operation then is as intuitively expected.

    EDIT: Multiple solutions are listed in "edit" sections after the question above, based on comments. A solution with variable, which allows for complex expressions if required, is shown below. If complex expression is not required, then as per OllieB's suggestion it is possible to reduce the assign to x_delayed(1 to x_delayed_dir'high) <= x_delayed(0 to x_delayed_dir'high-1):

    x_delayed(0) <= x;
    DELAYS : process(samp_clk)
      variable x_delayed_v : slv32_array(1 to NTAPS-1);
    begin
      if rising_edge(samp_clk) then
        for i in 1 to NTAPS-1 loop
          x_delayed_v(i) := x_delayed(i-1);  -- More complex operations are also possible
        end loop;
        x_delayed(1 to x_delayed_dir'high) <= x_delayed_v;
      end if;  -- rising_edge(samp_clk)
    end process;
    
    0 讨论(0)
  • 2020-12-06 03:09

    the reason you have a problem is that the logic thinks you have two things assigning into the same signal simultaneously - both the continues assignment and the register assignment loop. keep with the register implementation.

    edit
    if you have modelsim, you can use the 'trace x' option and see where it comes from.
    might be that the other simulator also have this feature, but for modelsim i'm certain it works

    0 讨论(0)
  • 2020-12-06 03:11

    In you not working example x_delayed(0) <= x;

    is aquvalent to

    process(x)
    begin
       x_delayed(0) <= x;
    end process;
    

    So the process will assign x_delayed(0) only when x changes. Because this is a signal asignment the x_delayed(0) will not change immediatly, it will change after a delta cycle. Therefore, when process DELAYS is called assignment for x_delayed(0) is not happened yet!

    Use a variable for x_delayed in your process, if you could.

    x_delayed(0) := x;
    
    0 讨论(0)
  • 2020-12-06 03:24

    During elaboration, drivers are created for all elements in x_delayed, regardless of the range of loop iterator. Hence, x_delayed(0) has two drivers associated with it. Std_Logic and Std_Logic_Vector are resoved types(i.e., when multiple drivers are associated with the signal with these types, the resolved function will determine the value of the signal by looking up a table in std package. Please refer to VHDL Coding Styles and Methodologies for more details.

    0 讨论(0)
提交回复
热议问题