|
VHDL Tutorial |
Case statements in VHDL | ||
|
Introduction Fundamental concepts Modelling concepts Elements of behaviour Elements of structure Analysis elaboration Lexical elements Identifiers Numbers Characters and strings Syntax descriptions Constants and variables Scalar type Integer types Floating point types Time type Enumeration types Character types Boolean type Bits type Standard logic Sequential statements Case statements Loop and exit statements Assertion statements Array types & array operations Architecture bodies Entity declarations Behavioral descriptions Wait statements Delta delays Process statements Conditional signal assignment Selected signal assigment Structural descriptions Library and library clauses Procedures Procedure parameters Signal parameters Default values Unconstrained array parameter Functions Package declarations and bodies Subprograms in package Use clauses Resolved signals and subtypes Resolved signals and ports Parameterizing behavior Parameterizing structure |
. Case Statements
If we have a model in which the behavior is to depend on the value of a single ex- pression, we can use a case statement. The syntax rules are as follows:
case_statement ⇐ [ case_label : ] case expression is ( when choices => { sequential_statement } ) { … } end case [ case_label ] ; choices ⇐ ( simple_expression I discrete_range I others ) { | … }
For example, suppose we are modeling an arithmetic/logic unit, with a control input, func, declared to be of the enumeration type:
type alu_func is (pass1, pass2, add, subtract);
Want To have highly paid VLSI jobs ?? then you may contact at
Contact : webmaster@freehost7com
We could describe the behavior using a case statement:
case func is when pass1 => result := operand1; when pass2 => result := operand2; when add => result := operand1 + operand2; when subtract => result := operand1 – operand2; end case;
At the head of this case statement is the selector expression, between the keywords case and is. The value of this expression is used to select which statements to exe- cute. The body of the case statement consists of a series of alternatives. Each alter- native starts with the keyword when and is followed by one or more choices and a sequence of statements. The choices are values that are compared with the value of the selector expression. There must be exactly one choice for each possible value. The case statement finds the alternative whose choice value is equal to the value of the selector expression and executes the statements in that alternative. We can include more than one choice in each alternative by writing the choices separated by the “|” symbol. For example, if the type opcodes is declared as
type opcodes is (nop, add, subtract, load, store, jump, jumpsub, branch, halt);
we could write an alternative including three of these values as choices:
when load | add | subtract => operand := memory_operand;
If we have a number of alternatives in a case statement and we want to include an alternative to handle all possible values of the selector expression not mentioned in previous alternatives, we can use the special choice others. For example, if the variable opcode is a variable of type opcodes, declared above, we can write
case opcode is when load | add | subtract => operand := memory_operand; when store | jump | jumpsub | branch => operand := address_operand; when others => operand := 0; end case;
In this example, if the value of opcode is anything other than the choices listed in the first and second alternatives, the last alternative is selected. There may only be one alternative that uses the others choice, and if it is included, it must be the last alternative in the case statement. An alternative that includes the others choice may not include any other choices.
An important point to note about the choices in a case statement is that they must all be written using locally static values. This means that the values of the choices must be determined during the analysis phase of design processing.
We can write a behavioral model of a branch-condition multiplexer with a select input sel; two condition code inputs cc_z and cc_c; and an output taken. The condition code inputs and outputs are of the IEEE standard-logic type, and the select input is of type branch_fn, which we assume to be declared elsewhere as
type branch_fn is (br_z, br_nz, br_c, br_nc);
We will see later how we define a type for use in an entity declaration. The entity declaration defining the ports and a behavioral architecture body are shown in Figure 3-4. The architecture body contains a process that is sensitive to the inputs. It makes use of a case statement to select the value to assign to the output.
library ieee; use ieee.std_logic_1164.all; entity cond_mux is port ( sel : in barnch_fn; cc_z, cc_c : in std_ulogic; taken : out std_ulogic );
end entity cond_mux; –– ––– –––– ––– –––– –––– ––– –––– ––– –––– ––– –––– –––– ––– –––– architecture demo of cond_mux is begin out_select : process (sel, cc_z, cc_c) is begin case sel is when br_z => taken <= cc_z; when br_nz => taken <= not cc_z; when br_c => taken <= cc_c; when br_nc => taken <= not cc_c; end case; end process out_select; end architecture demo;
|