Search code examples
selectif-statementvhdlxilinx

Can we use an "if" before with-select -VHDL


I have a code like the following,

with current_display select
char_output <= hours1 & '1' when "0111",
            hours2 & '1' when "1011",
        mins1 & '1' when "1101",
        mins2 & '1' when  "1110",
        "00000" when others;

but I would like to add two or more options to selecting the display of 7-segment. Adding only one option I make this one,

with set_alarm_switch & current_display select
        char_output <= hours1 & '1' when "00111",
                hours2 & '1' when "01011",
                mins1 & '1' when    "01101",
                mins2 & '1' when "01110",
                alarm_hours1 & '1' when "10111",
                alarm_hours2 & '1' when "11011",
                alarm_mins1 & '1' when  "11101",
                alarm_mins2 & '1' when  "11110",
                "00000" when others;

I wonder if I make this same coding with some "if" statements because if i were to add these guys another property, then I would have a complicated code.


Solution

  • I think all the current answers miss the question: "[...] make this same coding with some "if" statements [...]."

    Your current VHDL describes your desired circuit using a parallel assignment statement (with-select). You can easily convert this into multiple sequential statements inside a parallel process:

    assign_output_p : process (
        -- VHDL-2008: use "all" instead of each signal name
        set_alarm_switch,
        current_display,
        hours1,
        hours2,
        mins1,
        mins2,
        alarm_hours1,
        alarm_hours2,
        alarm_mins1,
        alarm_mins2
        )
    begin
    
        -- default assignment
        char_output <= (others => '0');
    
        if (set_alarm_switch = '1') then
            -- set alarm case
    
            case (current_display) is
            when "0111" => 
                char_output <= alarm_hours1 & '1';
            when "1011" => 
                char_output <= alarm_hours2 & '1';
            when "1101" => 
                char_output <= alarm_mins1 & '1';
            when "1110" => 
                char_output <= alarm_mins2 & '1';
            when others => 
                -- case for other current_display values
                -- including XUZ etc.
                null;
            end case;
    
        else
            -- default case
    
            case (current_display) is
            when "0111" => 
                char_output <= hours1 & '1';
            when "1011" => 
                char_output <= hours2 & '1';
            when "1101" => 
                char_output <= mins1 & '1';
            when "1110" => 
                char_output <= mins2 & '1';
            when others => 
                -- case for other current_display values
                -- including XUZ etc.
                null;
            end case;
        end if;
    
    end process assign_output_p;
    

    Also, I think you should evaluate if this big multiplexer makes sense in your application. Seven-segment displays are not that timing critical, so I advise to include a register stage at some point. Many companies choose to have a policy about this:

    1. Register inputs, leave outputs combinational => assumption that the next module will register them.
    2. Combinational inputs, register outputs => assumption that the previous module has registered outputs.