Title: ASIC 120: Digital Systems and StandardCell ASIC Design
1ASIC 120 Digital Systems and Standard-Cell ASIC
Design
- Tutorial 3 Intermediate VHDL
- November 9, 2005
2Outline
- Summary of previous tutorial
- Other signal values besides 0 and 1
- More VHDL data types
- Attributes, type definitions
- Generics
- Splitting a VHDL project across multiple design
units and files - if generate, for generate
- VHDL 1987 vs. 1993 vs. 2000
- Test benches
- time, procedures, variables, file access, etc.
3Summary of Previous Tutorial
- HDL design flow
- Format of a VHDL file
- Combinational statements
- assignments, conditionals, when else
- Sequential statements
- processes, if then else, case, loops
4Wires in the Real World
- We think of digital logic as being either 0 or 1
- Electricity on a real, physical wire is analog
- many different values
- Basic VHDL types do not take this into account
- bit
- bit_vector
- This is why we have the ieee.std_logic_1164
library - std_logic
- std_logic_vector
5std_logic_1164 Values
- Value Description
- U Uninitialized
- X Unknown
- 0 Strong 0 (driving)
- 1 Strong 1 (driving)
- Z High impedance
- W Weak unknown
- L Weak 0 (reading)
- H Weak 1 (reading)
- - Don't care
6std_logic_1164 Resolution Table
7Things to Watch For
- Never have two output driving one wire
- Tri-state buffers
- the usual way of connecting components to a bus
- compiler will often synthesize in a mux
- explicitly use a mux instead
- Summary only design with 0 and 1, but be
prepared to accept any value
8std_logic_1164 example
- Consider
- case Sel is
- when 00 gt
- X lt B
- when 10 gt
- X lt A
- when 1- gt
- X lt D
- when others gt
- X lt C
- end case
9std_logic_1164 example
- While this statement is valid, it is bad form
- unsynthesizable
- designing with values other than 0 and 1,
instead of just being prepared to accept them - case Sel is
- when 00 gt
- X lt B
- when 10 gt
- X lt A
- when others gt
- X lt C
- end case
10More On Numeric Data Types
- We have already seen
- bit, bit_vector
- std_logic, std_logic_vector
- Now we look at
- integer, real
- std_logic_arith
- numeric_std
11Arithmetic Data Types
- bit, bit_vector, std_logic, std_logic_vector are
useful for working with wires - However, cannot perform arithmetic operations
- not explicitly signed versus unsigned
- integer vs. real representations
12Arithmetic Data Types integer
- integer is to signed as bit_vector is to
std_logic_vector - Not well standardized across VHDL tools
- More on the real data type later
13Arithmetic Data Types std_logic_arith
- Obfuscated
- Use numeric_std instead
14Arithmetic Data Types numeric_std
- Example
-
- library ieee
- use ieee.std_logic_1164.all
- use ieee.numeric_std.all
- signal data unsigned(7 downto 0)
-
- data lt 137
- data lt data 1
15Arithmetic Data Types numeric_std
- numeric_std allows the usual arithmetic operators
to be used - Conversion to/from std_logic_vector
- unsigned()
- signed()
- std_logic_vector()
- Make sure your intermediate signals are large
enough - 4-bit number 4-bit number could equal 5-bit
number
16Attributes
- Consider
- process(clk)
- begin
- if (clkevent and clk 1) then
- if (resetn 0)
- q lt 0
- else
- q lt d
- end if
- end if
- end process
17Attributes
- event is an attribute of the clk signal
- the apostrophe () delimits the attribute
- An attribute is a characteristic of a VHDL object
- extra data attached to signal, pin, etc.
- Can be user-defined
18Attributes
- User-defined attributes are generally used to tap
into specific compilers functionality - Pre-defined attributes include
- event, last_event, last_value
- range, length, ascending
- left, right, high, low
- many more
19Attributes Example
- entity eight_regs is
- port( clk in std_ulogic
- data_in, load in std_ulogic_vector(7 downto
0) - data_out out std_ulogic_vector(7 downto 0)
- )
- end eight_regs
- architecture behavioural of eight_regs is
- begin
- signal data_q std_ulogic_vector(data_inrange)
- process(clk)
- begin
- if (clkevent and clk 1) then
- for i in data_inrange loop
- if (data_inleft 0) then -- reset
- data_q(i) lt 0
- elsif (load(i) 1) then -- load data
- data_q(i) lt data_in(i)
- end if
20Modular VHDL
- Using the previous example, what if I want 16
registers? - modify the existing code
- copy and paste
- components
21Components
- Components provide a way to take an
entity/architecture pair and reuse it - use it multiple times
- map signals to component inputs and outputs
22Component Example
- Using the eight_regs entity/architecture defined
earlier -
- architecture behavioural of sixteen_regs is
- component eight_regs
- port( clk in std_ulogic
- data_in, load in std_ulogic_vector(7 downto
0) - data_out out std_ulogic_vector(7 downto 0)
- )
- end component
- begin
- -- positional
- eight_regs1 eight_regs port map ( clock,
data_in(15 downto 8), - load(15 downto 8), data_out(15 downto
8)) - -- named
- eight_regs2 eight_regs port map ( clk gt
clock, data_in gt data_in(7 downto 0), - load gt load(7 downto 0), data_out gt
data_out(7 downto 0)) - end behavioural
23Generics
- Recall the attributes example
- instead of creating two components, what if we
doubled the size of data_in, data_out and load? - Generics allow us to be flexible with sizes of
things - compile time decisions
- passed from higher level into an entity
- Syntax
- generic(name type default_value)
24Attributes Example
- entity eight_regs is
- port( clk in std_ulogic
- data_in, load in std_ulogic_vector(7 downto
0) - data_out out std_ulogic_vector(7 downto 0)
- )
- end eight_regs
- architecture behavioural of eight_regs is
- begin
- signal data_q std_ulogic_vector(data_inrange)
- process(clk)
- begin
- if (clkevent and clk 1) then
- for i in data_inrange loop
- if (data_inleft 0) then -- reset
- data_q(i) lt 0
- elsif (load(i) 1) then -- load data
- data_q(i) lt data_in(i)
- end if
25Generics Example
- entity eight_regs is
- generic (bus_width integer 8)
- port( clk in std_ulogic
- data_in, load in std_ulogic_vector(bus_width-
1 downto 0) - data_out out std_ulogic_vector(bus_width-1
downto 0) - )
- end eight_regs
- architecture behavioural of eight_regs is
- begin
- signal data_q std_ulogic_vector(data_inrange)
- process(clk)
- begin
- if (clkevent and clk 1) then
- for i in data_inrange loop
- if (data_inleft 0) then -- reset
- data_q(i) lt 0
- elsif (load(i) 1) then -- load data
- data_q(i) lt data_in(i)
26Generics Example Up One Level
- Using the eight_regs entity/architecture defined
earlier -
- architecture behavioural of sixteen_regs is
- component eight_regs
- generic(bus_width integer)
- port( clk in std_ulogic
- data_in, load in std_ulogic_vector(bus_width
-1 downto 0) - data_out out std_ulogic_vector(bus_width-1
downto 0) - )
- end component
- begin
- eight_regs eight_regs
- generic map (bus_width gt 16)
- port map (clock, data_in, load, data_out)
- end behavioural
27Generics
- Note that the data type of the bus_width generic
is integer, not signed or unsigned - in this case its okay
28More On Data Types
- User defined data types
- Enumerations
- Arrays
29User Defined Data Types
- It is possible to define your own data types in
VHDL - Useful for
- reusing type declarations
- keeping variable types constant across or
variable declarations components - Much more can be said on this
- VHDL has many data types that we will continue to
introduce throughout these tutorials
30Enumerations
- Relate human-meaningful text to underlying binary
values - useful for state machines
- Example (includes definition of user-defined data
type t_states) - architecture test1 of test is
-
- type t_states is (STATE_BEGIN,
- STATE_RUN, STATE_TURN,
- STATE_END)
- signal curr_state t_states
- begin
- process
- begin
- wait until rising_edge(clk)
- if (curr_state STATE_BEGIN) then
- curr_state lt STATE_RUN)
- elsif
- end if
- end process
31Arrays
- Collections of other data types
- std_logic_vector is just an array of std_logic
- Multidimensional arrays possible
- useful for modelling memory
- sometimes design tools can automatically infer
memory from them, sometimes not
32Arrays
- Consider
- type t_arr_single is array (31 downto 0) of
std_logic - type t_arr_mult is array (31 downto 0, 31 downto
0) of std_logic - signal arr1 t_arr_single
- signal arr2 t_arr_mult
- Also possible
- signal arr3 array (31 downto 0) of std_logic
33Ways to Replicate Hardware
- How can we replicate VHDL functionality
- We have seen
- Manually (copy and paste)
- Components and Generics
- Loops
- Now we explore
- ifgenerate
- forgenerate
34Generate Statements
- Used to replicate concurrent constructs
- Only valid outside of processes
- Most useful for creating multiple component
instantiations
35if, for generate Example
- library ieee
- use ieee_std_logic_1164.all
- entity variable_shift_reg is
- generic( width integer 4
- depth integer 3
- one_or_two integer 1
- )
- port ( clk, reset in std_logic
- data_in in std_logic_vector(width-1 downto
0) - data_out out std_logic_vector(width-1 downto
0) - )
- end variable_shift_reg
36if, for generate Example
- architecture structural of variable_shift_reg is
- component single_register_A
- port(clk, reset in std_logic
- data_in in std_logic
- data_out out std_logic
- )
- end component
- component single_register_B
- port(clk, reset, reset2 in std_logic
- data_in in std_logic
- data_out out std_logic
- )
- end component
- begin
37if, for generate Example
- architecture structural of variable_shift_reg is
- component declarations on previous slide
- signal data_temp array(0 to depth) of
std_logic_vector(width-1 downto 0) - begin
- width_gen for i in width-1 downto 0 generate
- -- connect inputs
- data_temp(0)(i) lt data_in(i)
-
- -- generate middle shift registers (generic
one_or_two selects between _A and _B) - depth_gen for j in 0 to depth-1 generate
- A_gen if (one_or_two 1) then generate
- sr_gen single_register_A port map ( clk
gtclk, reset gt reset, - data_in gt data_temp(j)(i),
- data_out gt data_temp(j1)(i))
- end generate A_gen
- B_gen if (one_or_two 2) then generate
- sr_gen single_register_B port map ( clk
gtclk, reset gt reset, reset2 gt reset, - data_in gt data_temp(j)(i),
- data_out gt data_temp(j1)(i))
38if, for generate Example
- This example demonstrated how to construct a
variable-width, variable-depth shift register - i.e., a width-bit shift register with
depth-stages - You must name an if or for generate statement
- so the compiler has a base name to give to each
instance of a section
39VHDL Versions 1987, 1993, 2000
- There are three different revisions of VHDL
- Modern development tools understand all three
versions - Important to at least know they exist
- Often development tools implement VHDL
specification differently as well - Were going to postpone further discussion on
this for now, because we have more important
things to look at
40Test Benches
- Testing synthesized HDL code in hardware happens
in the final stages of development - time consuming, expensive, difficult
- Test benches allows us to simulate a design
- send test inputs
- check the outputs
- virtually connect different components together
to see how they interact
41Test Benches
- Consider a VHDL entity/architecture pair
- inputs and outputs will eventually be connected
to physical pins on an FPGA or ASIC - An entity/architecture pair without inputs or
outputs is a test bench - signals are generated internally
- think of it like a bread board sitting on your
desk
42Simple Test Bench Example
- library ieee
- use ieee.std_logic_1164.all
- entity test_and_gate is
- -- no inputs or outputs
- end test_and gate
- architecture stimulate of test_and_gate is
- component and_gate
- port(A, B in std_logic X out std_logic)
- end component
- constant CLK_PERIOD time 20 ns
- signal A, B, X std_logic
- begin
-
43Simple Test Bench Example
- Note that we have introduced CLK_PERIOD as a
constant - its data type is time
- time has a unit, in this case, ns or nanoseconds
44Simple Test Bench Example
-
- begin
- -- uut is unit under test
- uut and_gate port map(A gt A, B gt B, X gt X)
- process
- begin
- A lt 0 B lt 0
- wait for CLK_PERIOD
- assert (X 0) report 0,0 result incorrect!
severity ERROR - A lt 0 B lt 1
- wait for CLK_PERIOD
- assert (X 0) report 0,1 result incorrect!
severity ERROR - A lt 1 B lt 0
- wait for CLK_PERIOD
- assert (X 0) report 1,0 result incorrect!
severity ERROR
45Simple Test Bench Example
- Instead of wait until rising_edge(clk) we are
using wait for CLK_PERIOD - execution of that process pauses for given amount
of time - Final wait statement will pause forever
- wait for is unsynthesizable
- impossible to specify a specific amount of time
in hardware - however, this is very useful for test benches
46Clocking Test Benches
- Often, the clock will be run independently of the
input stimulus - Consider
- process
- begin
- clk lt 0
- wait for CLK_PERIOD
- clk lt 1
- wait for CLK_PERIOD
- end process
-
- process
- begin
- wait until rising_edge(clk)
- apply input stimulus to unit under test
- wait until rising_edge(clk)
- check output of unit under test for
correctness
47Clocking Test Benches
- In this way, we can co-ordinate input stimulus
across multiple units under test
48More on Test Benches
- Another useful test bench tool in VHDL is file
input and output - obviously not synthesizable
49Functions and Procedures
- Functions and procedures in VHDL are useful for
defining a block of functionality that can be
re-used - similar to functions in C
- not the same thing as processes
- Due to time constraints, we wont cover them in
any further detail
50Variables
- Variables can be used to store intermediate
values within a process - can also be used in functions and procedures
- They are NOT the same thing as signals
- use them wisely
- Due to time constraints, we wont cover them in
any further detail
51What Ive Skipped
- Blocks, Libraries/Packages
- other modularity features
- weve had a taste of libraries and packages
- library ieee
- Configurations
- way to select among multiple architectures
- Constants
- like generics, but within one file
- File access
- useful for test benches, not synthesizable
- Functions, procedures, variables
52Preview of Next Tutorial
- Digital Systems Concepts
- The FPGA LEs, buffers and routing, other
resources - Bus interfaces
- Register files
- Other FPGA resources clocks, memories, memory
interfaces, multipliers, etc. - Soft- and hard-processors in FPGAs
53Summary
- Summary of previous tutorial
- Other signal values besides 0 and 1
- More VHDL data types
- Attributes, type definitions
- Generics
- Splitting a VHDL project across multiple design
units and files - if generate, for generate
- VHDL 1987 vs. 1993 vs. 2000
- Test benches
- time, procedures, variables, file access, etc.
54UW ASIC Design Team
- www.asic.uwaterloo.ca
- reference material
- Accolade VHDL reference (excellent!)
- http//www.acc-eda.com/vhdlref/
- many of todays examples came from here
- Bryce Leungs tutorials (UW ASIC website)
- Mike Goldsmiths tutorials (UW ASIC website)
- your course notes
- my contact info
- Jeff Wentworth, jswentwo_at_engmail.uwaterloo.ca