Example:
with func_sel select ALUout <= '0' & (a OR b) when OPOR, '0' & (a AND b) when OPAND, '0' & (a XOR b) when OPXOR, add_w_carry(a,b,cin) when OPADD, -- where add_w_carry returns a value -- one greater than the size of its inputs XOUT when OTHERS reg_clk: block (rising_edge(clk)) begin ResReg <= guarded ALUout(1 to dout'length); end block; cout <= ALUout(0) after cout_delay; dout <= ResReg after reg_delay;Example
O_bus <= ALU ( A_bus, B_bus, cy_in, ctl.func);In this statement we are ignoring the responsibility of the ALU function to set status flags (like C, S, N, V) because a function can return only one value. If we create
procedure ALU ( X, Y : in bit_vector; Cin : bit; F : out bit_vector; C,S,N,V : out bit; ctl_func : in ALU_ops );then we can invoke the procedure ALU to update the control flags with
ALU ( A_bus, B_bus, O_bus, Qc, C,S, N, V, ctl.func);
label : block ( guard_expression ) begin . . . sig_ident <= guarded waveform(s) . . . end label ;Example: A VERY simple CPU Data Unit
CPU_p0: block ( enable = '0' ) begin A_bus <= guarded Register_file (IR.dest); B_bus <= guarded Register_file (IR.source); O_bus <= ALU ( A_bus, B_bus, ctl.func); end CPU_p0; CPU_p1: block ( enable = '1' ) begin Register_file (IR.dest) <= guarded O_bus; end CPU_p1;This description assumes the earlier definition of the buses and the IR register as bit_vector signals, and Register_file as an array of bit_vector signals. ALU is a function returning a bit_vector value and may have been defined in the declarations part of the architecture.
In the upper block the meaning of the "guard" is that the Abus and Bbus receive the content of theRegister_file only while the enable is low.
In the lower block the Register file is update only while the enable is high.
signal Q : bit_vector ( 0 to REGSIZE-1) register ; signal O_bus : bit_vector ( 0 to 15 ) bus;Signals which are to be the targets of guarded signal assignments must be declared to be either bus or register kind. You should declare these consistent with the way in which you are using the signal.
There is a separate DRIVER for a signal for each process (or concurrent signal assignment statement - of any kind) in which there is an assignment to that signal. For the example above, there will be some combination of five processes / concurrent statements for the five components shown. Correspondingly, there will be five drivers for DATA_BUS.
Each DRIVER is a WAVEFORM -- a list of value/time events waiting to occur to update the value of the signal. Whenever it is time for a signal update to occur, the presence of multiple drivers means that the current value of all the other drivers must be considered by a BUS RESOLUTION function, usually included as part of the TYPE declaration for that kind of signal and stored up in the corresponding package.
The behavior of signals with multiple drivers tends to be technology specific. The most common models are
The models constructed to represent such behaviors are called BUS RESOLUTION FUNCTIONS. Unlike virtually every other language, VHDL provides complete flexibility in the creation of bus resolution functions, yet allows them to be kept well hidden from view in package declarations.
subtype type_name is res_func_name base_type ;
Example:
subtype OC_bit is Wired_And bit ; Then we can declare signal IRQ : OC_bit ; signal DATA_BUS : array (0 to 7) of OC_bit;Example: In package std_logic_1164, the type declaration for a nine valued std_ulogic is:
type std_ulogic is ('U','X','0','1','W','Z','L','H','-');But we used the resolved logic type std_logic in our example of the ALU. That is declared
subtype std_logic is resolved std_ulogic;
The function resolved is described in the package body.
The Wired_And function is declared in the same package where OC_bit was declared:
function Wired_And ( in_driver : in bit_vector ) return bit is variable result : bit := '1'; begin for i in in_driver'range loop if in_driver(i) = '0' then result := '0'; exit; end if; end loop; return result ; end Wired_And;
Guarded signal assignment statement
bb: block ( rising_edge ( clock ) ) Z <= guarded X; end bb;is virtually the same as saying
if rising_edge (clock) then Z <= X; -- where Z has been declared to be a signal -- of kind register.If the RHS signal is a bus, then the bus resolution function must specify what is assigned to the signal if there is no driver (similar to the "else" situation previously discussed).
Example:
function tristate (in_driver : std_logic_vector ) return std_logic is begin if in_driver'length = 0 then return "Z'; else ....
Revised 10/11/95