Question

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.

Was it helpful?

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.

OTHER TIPS

Personally I would treat each 7 segment display as its own signal. You might have good reasons not to do this, but it makes the most sense to me. So your code might look like this:

seg3 <= hours_tens_time when current_display = '1' else hours_tens_alarm;
seg2 <= hours_ones_time when current_display = '1' else hours_ones_alarm;
seg1 <= mins_tens_time  when current_display = '1' else mins_tens_alarm;
seg0 <= mins_ones_time  when current_display = '1' else mins_ones_alarm;

This way, you can add more signals as you want to on seg3, 2, 1, 0, if you want to add a stopwatch or whatever you can do that, just expand this conditional assignment above. Give your signals more meaningful names too. hours1 hours2 doesn't mean anything.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top