0

If this can't be done, just leave me with a simple "no" plus perhaps a short answer as to why, but I'd just like to double check this can't be done.

I have this process:

process(clk_p)
begin
    if rising_edge(clk_p) then
        if rst_i = '1' then
            stored_events <= (others => '0');
        else
            if mode_triggered = '1' and ptr = 0 and read_state = ST_ENABLE then
                stored_events <= stored_events;
            elsif mode_triggered = '1' then
                stored_events <= stored_events + 1;
            elsif ptr = 0 and read_state = ST_ENABLE then
                stored_events <= stored_events - 1;
            end if;
        end if;
    end if;
end process;

Yup, it's not great which us why I'm going to help the synthesis by turning it into a proper case mux.

You could do something like this:

sel(0) <= '1' when mode_triggered= = '1' else '0';
sel(1) <= '1' when ptr = 1 else '0'; 
sel(2) <= '1' when read_state = ST_ENABLE else '0';

case sel is 
    when "111" => 
        stored_events <= stored_events; -- and so on...

Though since I'm going to be changing several processes, I cba to make make even more signal names. So...

I was wondering if there was some way I could so like (though not entirely sure how the final when others would work out ):

case mode_triggered, ptr, read_state is 
    when '1', 0, ST_ENABLE =>
        stored_events <= stored_events;
blackgreen
  • 34,072
  • 23
  • 111
  • 129
fiz
  • 906
  • 3
  • 14
  • 38
  • Your first process example is already a mux. It's a mux for save, increment and decrement plus a D flipflop with sync reset. This mux is normally absorbed into a LUT. So if you open your design in RTL view and look for the LUT equation you will find the mux equation in it. – Paebbels Mar 24 '15 at 11:41
  • on the next synthesis, I'll look into it. Just looks a bit messy, I usually prefer the look of a case statement. If there's no new way of writing the mux the way I want, I'll just use extra signals. – fiz Mar 24 '15 at 12:03
  • also should the above not finish with an `else` to catch all other combinations? – fiz Mar 24 '15 at 12:08
  • 1
    The else case is implizitely covered, because it's hosted in a clocked process otherwise it would cause latches. – Paebbels Mar 24 '15 at 12:23

2 Answers2

1

You can probably achieve what you seek using records and/or VHDL-2008 syntax, but I recommend against it.

Not only will you lose in readability, I seriously doubt you would get any synthesis gain.

When I look at your code, I don't see any mux. Instead, I see an up/down counter with synchronous reset and clock enable port. You could write it like this if you want:

clk_en <= '0' when mode_triggered = '1' and ptr = 0 and read_state = ST_ENABLE else
          '1' when mode_triggered = '1' or (ptr = 0 and read_state = ST_ENABLE) else
          '0';
up <= '1' when mode_triggered = '1' else '0';

process(clk_p)
begin
    if rising_edge(clk_p) then
        if rst_i = '1' then
            stored_events <= (others => '0');
        elsif clk_en = '1' then
            if up = '1' then
                stored_events <= stored_events + 1;
            else
                stored_events <= stored_events - 1;
            end if;
        end if;
    end if;
end process;

All three way to write the code should lead to the same netlist (hopefully), they only differ in readability. Personally, I prefer your first attempt, as it comes from the function you are achieving, but it all come to preference. I also dislike the mux approach (for this case).

As a rule of thumb, don't write to help the synthesizer unless you have too. Look at synthesis reports and generated netlist and adjust only if you don't like what you see. The synthesizer is better at extracting the circuit from code like your first attempt than we human are at understanding the function of a code full of muxes and logic gates.

Jonathan Drolet
  • 3,318
  • 1
  • 12
  • 23
  • Interesting, thankyou. I'll keep it the way I did it at first then. I was curious as to alternative syntax for the problem and as ever there was indeed always something new to learn =D – fiz Mar 24 '15 at 14:00
1

Another variant (up and down are boolean) may help readability

down <= ptr = 0 and read_state = ST_ENABLE;
up   <= mode_triggered and not down;

process(clk_p)
begin
    if rising_edge(clk_p) then
        if rst_i = '1' then
            stored_events <= (others => '0');
        else
            if up then
                stored_events <= stored_events + 1;
            elsif down then
                stored_events <= stored_events - 1;
            end if;
        end if;
    end if;
end process;