INTRO TO VLSI DESIGN CPE 448 VHDL Tutorial

  • Slides: 22
Download presentation
INTRO TO VLSI DESIGN (CPE 448) (VHDL Tutorial) Prof: Asuif Mahmood

INTRO TO VLSI DESIGN (CPE 448) (VHDL Tutorial) Prof: Asuif Mahmood

} Files can be used to store data to be loaded into a model

} Files can be used to store data to be loaded into a model when it is run, or to store the results produced by simulation. } VHDL also provides specialized versions of file operations for working with text files. } VHDL provides sequential access to files using operations, such as “open”, “close”, “read” and “write”, that are familiar to users of conventional programming languages. } File Declarations: file identifier { , … }: subtype_indication [[ open file_open_kind_expression ] is string_expression] FILES and INPUT/OUTPUT

} If a file is opened in a read mode, successive elements of data

} If a file is opened in a read mode, successive elements of data are read from the file using the read operation. } Reading starts from the first element in the file, and each time an element is read the file position advances to the next element. } We can use the endfile operation to determine when we have read the last element in the file. Syntax: type file_type is file of element_type; read and endfile operations are implicitly declared as procedure read ( file f : file_type; value : out element_type); function endfile ( file f : file_type) return boolean; Reading from Files

Library ieee; Use ieee. std_logic_1164. all; entity ROM is generic (load_file_name : string); port(

Library ieee; Use ieee. std_logic_1164. all; entity ROM is generic (load_file_name : string); port( sel : in std_logic; address : in std_logic_vector; data : in std_logic_vector); end entity ROM; architecture behavioral of ROM is begin behavior : process is subtype word is std_logic_vector( o to data’length – 1); type storage_array is array (natural range 0 to 2**address’length – 1 ) of word; variable storage : storage_array; variable index : natural; --other declarations type load_file_type is file of word; file load_file: load_file_type open read_mode is load_file_name; begin --load ROM contents from load_file index : = 0; while not endfile (load_file) loop read ( load_file, storage(index)); index : = index + 1; end loop; --respond to ROM accesses loop --- other instructions end loop; end process behavior; end architecture behavioral; Reading from Files (Example)

} If a file is open in write mode, a new empty file is

} If a file is open in write mode, a new empty file is created in the host computer’s file system, and successive data elements are added using the write operation. } implicitly declared as procedure write ( file f : file_type; value : in element_type); Writing to Files

architecture instrumented of CPU is type count_file is file of natural; file instruction_counts: count_file

architecture instrumented of CPU is type count_file is file of natural; file instruction_counts: count_file open write_mode is “instructions”; begin interpreter : process is variable IR : word; alias opcode : byte is IR(0 to 7); variable IR : word; type counter_array is array (0 to 2**address’length – 1 ) of natural; variable counters : counter_array: =(others =>0); begin --initialize the instruction set interpreter instruction_loop: loop --fetch the next instruction into IR --decode the instruction opcode_number : = convert_to_natural(opcode); counters(opcode_number) : = counters(opcode_number)+1; -- execute the decoded instruction case opcode is when halt_opcode => exit instruction_loop; end case; end loop instruction_loop; for index in counters’range loop write (instruction_counts, counters(index)); end loop; wait; -- program finished, wait forever end process interpreter; end architecture instrumented; Writing to Files (Example)

} The concept of type is very important when describing data in a VHDL

} The concept of type is very important when describing data in a VHDL model. } The type of a data object defines the set of values that the object can assume, as well as the set of operations that can be performed on those values. } A scalar type consists of single, indivisible values. Scalar Data Types and Operations

} Both constants and variables need to be declared before they can be used

} Both constants and variables need to be declared before they can be used in a model. } A declaration simply introduces the name of the object, defines its type and may give it an initial value. constant number_of_bytes : integer : = 4; constant number_of_bits : integer : = 8*number_of_bytes; constant e : real : = 2. 71828; constant prop_delay : time : = 3 ns; variable index: integer : = 0; variable start, finish : time : = 0 ns; CONSTANTS and VARIABLES

} Example: architecture sample of ent is constant pi : real : 3. 14159

} Example: architecture sample of ent is constant pi : real : 3. 14159 begin process is variable counter : integer; begin --do anything end process; end architecture sample; } One restriction on where a variable declaration may occur is that it may not be placed so that the variable would be accessible to more than one process. } The exception to this rule is if a variable is declared specially as shared variable. CONSTANTS and VARIABLES (cont. )

} A scalar type is one whose value are indivisible. } type apples is

} A scalar type is one whose value are indivisible. } type apples is range 0 to 100; } type oranges is range 0 to 100; package int_types is type small_int is range 0 to 255; end package int_types; use work. int_types. all; entity smaller_adder is port ( a, b s end entity small_adder; : : in small_int; out small_int); SCALAR TYPES

} A predefined type integer is included, which includes all whole numbers representable on

} A predefined type integer is included, which includes all whole numbers representable on a particular host computer. type day_of_month is range 0 to 31; type year is range 0 to 2100; variable today: day_of_month : = 19; variable start_year: year : = 2002; **It is illegal to make the assignment: start_year : = today; INTEGER TYPES

type INPUT_LEVEL is range – 10. 0 to 10. 0; type probability is range

type INPUT_LEVEL is range – 10. 0 to 10. 0; type probability is range 0. 0 to 1. 0; variable input_A: input_level; FLOATING-POINT TYPES

} Examples: type resistance is range 0 to 1 E 9 units ohm; kohm

} Examples: type resistance is range 0 to 1 E 9 units ohm; kohm = Mohm = end units resistance; **We can use them as 5 ohm 22 ohm 1000 ohm; 1000 kohm; 4 kohm type time is range implementation defined units fs; ps=1000 fs; ns=1000 ps; us=1000 ns; ms=1000 us; sec=1000 ms; min=60 sec; hr=60 min; end units time; PHYSICAL TYPES

type alu_function is (disable, pass, add, subtract, multiply, divide); type octal_digit is ( ‘

type alu_function is (disable, pass, add, subtract, multiply, divide); type octal_digit is ( ‘ 0’, ‘ 1’, ‘ 2’, ‘ 3’, ‘ 4’, ‘ 5’, ‘ 6’‘, 7’); variable alu_op: alu_function; variable last_digit: octal_digit : = ‘ 0’; and make assignments to them: alu_op : = last_digit : = subtract; ‘ 7’; ENUMERATION TYPES

} When we write complex behavioral models it is useful to divide the code

} When we write complex behavioral models it is useful to divide the code into sections, each dealing with a relatively selfcontained part of the behavior. } There are two kinds of subprograms: procedures and functions. } Procedure encapsulates a collection of sequential statements that are executed for their effect. } Function encapsulates a collection of statements that compute a result. } Thus a procedure is a generalization of a statement, whereas a function is a generalization of an expression. Subprograms

} There are two aspects to using procedures in a model: } First the

} There are two aspects to using procedures in a model: } First the procedure is declared. } Then elsewhere the procedure is called. procedure identifier [ (parameter_interface_list) ] is { subprogram_declarative_part } begin { sequential_statement } end procedure [ identifier ]; PROCEDURES

procedure addu ( a, b : in word 32; result : out word 32;

procedure addu ( a, b : in word 32; result : out word 32; overflow : out Boolean ) is variable sum: word 32; variable carry: bit : = ‘ 0’; begin for index in sum’reverse_range loop sum(index): =a(index) xor b(index) xor carry; carry: =(a(index) and b(index) ) or (carry and (a(index) xor b(index) ) ); end loop; result: =sum; overflow: =carry = ‘ 1’; end procedure addu; **A call to this procedure may appear as follows: variable PC, next_PC: word 32; variable overflow_flag: boolean; addu ( PC, X” 0000_0004”, next_PC, overflow_flag); PROCEDURES (Example)

} The syntax rule for a function declaration is very similar to that for

} The syntax rule for a function declaration is very similar to that for a procedure declaration: function identifier [ (parameter_interface_list) ] return type_mark is { subprogram_declarative_part } begin { sequential_statement } end function [ identifier ]; FUNCTIONS

function limit ( value, min, max : integer) return integer is begin if value

function limit ( value, min, max : integer) return integer is begin if value > max then return max; elsif value < min then return min; else return value; end if; end function limit; } Call to this function might be included in a variable assignment statement, as follows: new_temperature : = limit ( current_temperature + increment, 100); FUNCTIONS

} A VHDL package is simply a way of grouping a collection of related

} A VHDL package is simply a way of grouping a collection of related declarations that serve a common purpose. } They might be a set of subprograms that provide operations on a particular type of data. } Or they might just be the set of declarations needed to model a particular design. } The important thing is that they can be collected together into a separate design unit that can be worked on independently and reused in different parts of a model. package identifier is { package_declarative_item } begin { sequential_statement } end package [ identifier ]; Package

package cpu_types is constant word_size : positive : = 16; constant address_size : positive

package cpu_types is constant word_size : positive : = 16; constant address_size : positive : = 24; subtype word is bit_vector (word_size-1 downto 0); subtype address is bit_vector (address_size-1 downto 0); type status_value is (halted, idle, fetch, mem_read, mem_write, io_read, io_write, int_ack); subtype opcode is bit_vector (5 downto 0); function extract_opcode (instr_word: word) return opcode; constant op_nop : opcode : = “ 000000”; constant op_breq : opcode: = “ 000001”; constant op_brne : opcode: = “ 000010”; constant op_add : opcode : = “ 000011”; end package cpu_types; Package (Example)

entity address_decoder is port ( addr : in work. cpu_type. address; status : in

entity address_decoder is port ( addr : in work. cpu_type. address; status : in work. cpu_type. status_value; mem_sel, int_sel, io_sel : out bit); end entity address_decoder; architecture behavioral of cpu is -- define constant mem_low: work. cpu_type. address: =X” 000000”; begin interpreter : process is variable instr_reg : work. cpu_types. word; variable instr_opcode : work. cpu_types. opcode; begin -- initialize loop -- fetch instruction instr_opcode: = work. cpu_types. extract_opcode( instr_reg): case instr_opcode is when work. cpu_types. op_nop => null; when work. cpu_types. op_breq => null; end case; end loop; end process interpreter; end architecture behavioral; Package (Example)