Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

New to VHDL, problem with variables/signal?

I am new to VHDL but trying to learn. I would like to make an alarm clock, i decided to start with a mux, 4bit wide 2 to 1. I am using the DE1 board, for testing i want to conect the mux to the switches and show the output on the green leds based on the selector switch. I think that my problem is somehting with the variable scope. can anyone offer any input on the following code?

The error i get right now is:

Error (10482): VHDL error at Lab1.vhd(49): object "S" is used but not declared

Error (10482): VHDL error at Lab1.vhd(47): object "S" is used but not declared


LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY lab1 IS
    PORT (
        SW :   IN STD_LOGIC_VECTOR(9 DOWNTO 0);
        HEX0 : OUT STD_LOGIC_VECTOR(0 TO 6);
        LEDR : OUT STD_LOGIC_VECTOR(9 DOWNTO 0);
        LEDG : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
        );
    END lab1;
ARCHITECTURE Behavior OF lab1 IS
    COMPONENT mux4bit2to1
        PORT (
            A, B, C, D : IN STD_LOGIC_VECTOR(1 DOWNTO 0); --MUX Inputs
            W, X, Y, Z : OUT STD_LOGIC; --MUX Outputs
            S : IN STD_LOGIC --Selector bit
        );
    END COMPONENT;
    
    COMPONENT char7seg
        PORT ( 
            N : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
            Display : OUT STD_LOGIC_VECTOR(0 TO 6)
        );
    END COMPONENT;
    
    BEGIN
    mux1 : mux4bit2to1 port map(
        A(0) => SW(0),
        A(1) => SW(5),
        B(0) => SW(1),
        B(1) => SW(6),
        C(0) => SW(2),
        C(1) => SW(7),
        D(0) => SW(3),
        D(1) => SW(8),
        W  => LEDG(0),
        X  => LEDG(1),
        Y  => LEDG(2),
        Z  => LEDG(3),
        S  => SW(9)
    );
    muxselect: PROCESS (S)
    BEGIN
        case S is 
            when '0' =>
             W <= A(0);
             X <= B(0);
             Y <= C(0);
             Z <= D(0);
            when '1' =>
             W <= A(1);
             X <= B(1);
             Y <= C(1);
             Z <= D(1);
            when OTHERS =>
             W <= '0';
             X <= '0';
             Y <= '0';
             Z <= '0';
        END CASE;
    END PROCESS;
            
            
    LEDR <= SW;
END Behavior;

8 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    S is a port on the mux4bit2to1 component not a signal in he lab1.

    So to answer your question about scopes: The scope of variables are only in processes, and the scope of signals is only in the architecture.

    The scope of the in and outputs is only in the entities architecture for reading and writing, and only for "interconnecting" in a "parent" architecture.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I defined S in the port map, i thought that was how i access variables listed in a component? Do i need to add additional variables to then use them in this switch statement? Can you offer any coding suggestions or maybe a place to look, i have been searching online but i am still confused. I was trying to follow along with the altera labs that were included in the CD but i got lost. I pick up quickly but i just need help getting started.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    To help you understand your mistake, perform the following;

    1. Move muxselect into a component

    2. Draw blocks for your low-level components

    - Use rectangles for your lower-level components, eg., muxselect, mux4bit2to1, and char7seg, and put the port names inside the rectangles.

    3. Draw a rectangle around your low-level components, as your top-level design, and draw wires from the muxselect, mux4bit2to1, and char7seg ports to the top-level ports.

    When you've finished drawing that diagram, you will see that there is a connection missing, i.e., your muxsel signal S has no corresponding "wire" in your block diagram. In VHDL you create that internal signal using "signal S : std_logic;" at the beginning of the architecture (where you have the component definitions).

    Once you get code that Quartus will synthesize, you can use "Tools->Netlist Viewer->RTL Viewer" and you'll see that Quartus draws you a block diagram :)

    Cheers,

    Dave
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    In Addition, Just to stop all the confusion, your code contains no variables at all. Variables are different from signals. But I suggest you keep to signals until you know what you're doing.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I gave up, with this ended up putting it together in the schematic view, is there a way to see the generated code so i can review Quartus's method? How close was i on the original code?

    --- Quote End ---

    You haven't given up, you're just beginning to understand :)

    In your schematic you have a 4-bit signal that goes between the mux and BCD decoder. In VHDL, these 4-bits cannot be called ledg(3 downto 0) because that signal would be defined as an "out" port in the top-level entity, and you cannot read "out" ports from within your VHDL, you can only drive outputs. Because of this, you would introduce the internal "signal s : std_logic_vector(3 downto 0)", and you would use s to connect the mux and BCD decode, and to drive the ledg output, i.e., ledg <= s;

    Try to modify your original VHDL design to match.

    Cheers,

    Dave
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks Dave, that makes sense to me now, but i think i'm still stuck trying to access the ports defined within a component, I have been playing with this code for several days now, even gutted out the BCD decoder just to see if i can design just the MUX

    I got rid of the first error message, but now i get a new error as soon as the compiler enters the case process saying that "W" is used but not defined.

    I was able to draw up the schematic, compile and do a quick simulation in 20min :) I think i need to learn a little more of the VHDL basics first

    This is the code right before i moved to the schematic version, i wanted to use individual components because i would like to grow this project, the next step i am going to substitute the switch inputs (0-3, 5-8) for a pair of BCD counters.

    With this the output of the mux was going to drive the LEDG array, i'm assuming that the signals listed in the port map are not available to the case process? I have tried numerous variations and locations of the signal and variable declarations but it still fails.

    
    LIBRARY ieee;
    USE ieee.std_logic_1164.all;
    ENTITY lab1 IS
        PORT (
            SW :   IN STD_LOGIC_VECTOR(9 DOWNTO 0);
            HEX0 : OUT STD_LOGIC_VECTOR(0 TO 6);
            LEDR : OUT STD_LOGIC_VECTOR(9 DOWNTO 0);
            LEDG : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
            S : IN STD_LOGIC --Selector bit
            );
        END lab1;
    ARCHITECTURE Behavior OF lab1 IS
        COMPONENT mux4bit2to1
            PORT (
                A, B, C, D : IN STD_LOGIC_VECTOR(0 TO 1); --MUX Inputs
                W, X, Y, Z : OUT STD_LOGIC; --MUX Outputs
                S : IN STD_LOGIC
            );
        END COMPONENT;
        
        BEGIN
        mux1 : mux4bit2to1 port map(
            A(0) => SW(0),
            A(1) => SW(5),
            B(0) => SW(1),
            B(1) => SW(6),
            C(0) => SW(2),
            C(1) => SW(7),
            D(0) => SW(3),
            D(1) => SW(8),
            W  => LEDG(0),
            X  => LEDG(1),
            Y  => LEDG(2),
            Z  => LEDG(3),
            S  => S
        );
        
        muxselect: PROCESS (S)
        BEGIN
            case S is 
                when '0' =>
                 W <= A(0);
                 X <= B(0);
                 Y <= C(0);
                 Z <= D(0);
                when '1' =>
                 W <= A(1);
                 X <= B(1);
                 Y <= C(1);
                 Z <= D(1);
                when OTHERS =>
                 W <= '0';
                 X <= '0';
                 Y <= '0';
                 Z <= '0';
            END CASE;
        END PROCESS;
                
        S  <= SW(9);        
        LEDR <= SW;
    END Behavior;
    

    -scott-
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    i'm assuming that the signals listed in the port map are not available to the case process?

    --- Quote End ---

    Why assume, when you can read a book on VHDL or Google the question? VHDL input ports can be "read" within your VHDL process, VHDL output ports cannot. This means any input to the top-level entity can be used within a select statement.

    The concept that you are stuck on is that you are somehow thinking the existence of a port named W, X, Y, or Z, *ALSO* creates a signal (wires) by those names. That is not how it works. In your top-level design you need to create the wires you see in your schematic. You can call them anything you want, but it can make more sense to name them the same as the ports they connect to.

    Hint: add 1-bit signals w, x, y, and z. Connect those signals to the w, x, y, and z ports on your mux4bit2to1 component, and then drive the LEDG outputs with those signals.

    Cheers,

    Dave