From Hamsterworks Wiki!
Please make sure that you have completed the earlier modules of FPGA course.
Having problems with your code? Do I need to change something? Want a reference solution to the project? Email me at "email@example.com", after removing the "nospam-" bit. I'll try to get back to you in a day or so.
Aim of module
- To build and test your first multi-module design
Using more than one source module in a design
Just like in software, there quickly comes a time when putting every in one source file is no longer practical. There is also the need to separate designs into functional units that can be tested independently of each other.
VHDL achieves this though "architectures", "components", "entities" and "instances" - we've already breezed over all of this.
- The "entity" statement defines the 'inside' view of a module's interface
entity mymodule is Port ( input1 : in STD_LOGIC_VECTOR (3 downto 0); output1 : out STD_LOGIC_VECTOR (3 downto 0)); end mymodule;
This is at the top of the defining module, following the "use" statements.
- The "architecture" defines how a component works - it contains all the internal signals and sub-components, and all the internal logic:
architecture Behavioral of mymodule is begin output1 <= input1; end Behavioral;
This is usually the bulk of the module, and appears after the entity statement.
- The "component" statement defines the 'external' view of the module, and is appears in the module that uses the component:
COMPONENT mymodule PORT( input1 : IN std_logic_vector(3 downto 0); output1 : OUT std_logic_vector(3 downto 0)); END COMPONENT;
Component declarations appear in the same area of the code as the signal declarations
- The "instance" statement describes the connections of the component inside the containing module - it is this that actually triggers the component to be included in the final design:
Inst_mymodule: mymodule PORT MAP( input1 => input_signal1, output1 => output_signal1 );
These can be intermingled with the assignment statements and processes, but not contained withing a process block. One source of frustration for me is that when signals are mapped they can not be operated on (e.g. 'input_a => signal_a' is valid but 'input_a => NOT(signal_a)' is not). Oh, and if you don't want to use an output, you can map it to the keyword "open" (e.g. "output1 => open").
Creating a module using the wizard
The easy way to do create a new module is using the "New Source..." wizard.
On the first screen give the module a name:
Then define the interface - don'e worry if you are not 100% sure of the signals, you can change them directly in the source afterwards:
You are then presented with a summary screen, and click finish.
Once you have a new module you can highlight it and under "Design Utilities" you can run the "View HDL instantiation Template" process to get a template that you can cut and paste as needed:
It will look something like this:
COMPONENT mymodule PORT( input1 : IN std_logic_vector(3 downto 0); output1 : OUT std_logic_vector(3 downto 0) ); END COMPONENT; Inst_mymodule: mymodule PORT MAP( input1 => , output1 => );
In most designs the very top level module ends up containing very little logic and resembles a big wiring loom - with a lot of instances of smaller components and the signals that interconnect them.
- Create a new module - a 30 bit counter called "counter30", with the following external signals:
- clk : in STD_LOGIC
- enable : in STD_LOGIC
- count : out STD_LOGIC_VECTOR(29 downto 0)
The internal design is up to you, but project 6.1 will be pretty close
- View the 'Instantiation template' for your component. Copy the component declaration into your switches_leds.vhd source
- In switches_leds create an instances of counter30.
- Connect the counter's 'count' output to a bus called count1
- Connect the "enable" signal to switch 0
- Connect the the clock.
- Connect the top four bits of count1 to LEDs(3 downto 0). Remember to add a signal definition for 'count1'.
- Implement the design and test that it works as expected - switches 0 should enable the counter driving the lower four LEDs. It is usual to get a lot of warnings about unused signals that will be timed from the design. This is expected as we are only using the top four bits of the counters.
- Create a second instance of counter30 in the switches_leds vhd source.
- have it drive signals a bus called 'count2'
- connect the "enable" signal to switch 1.
- connect the top four bits of 'count2' to LEDs(7 downto 4)
- Check that this too works as expected
Ready to carry on?
Click here to carry on to the next module.