📄 chapter7_models.vhd
字号:
package TIMING_CONTROL is
type TIMING is (MIN,MAX,TYP,DELTA);
constant TIMING_SEL: TIMING := TYP;
function T_CHOICE(TIMING_SEL: TIMING; TMIN,TMAX,TTYP: TIME)
return TIME;
end TIMING_CONTROL;
package body TIMING_CONTROL is
function T_CHOICE(TIMING_SEL: TIMING; TMIN,TMAX,TTYP: TIME)
return TIME is
begin
case TIMING_SEL is
when DELTA => return 0 ns;
when TYP => return TTYP;
when MAX => return TMAX;
when MIN => return TMIN;
end case;
end T_CHOICE;
end TIMING_CONTROL;
use work.TIMING_CONTROL.all;
entity OR2_TV is
generic(TMIN,TMAX,TTYP: TIME);
port(I1,I2: in BIT; O: out BIT);
end OR2_TV;
architecture VAR_T of OR2_TV is
begin
O <= I1 or I2 after T_CHOICE(TIMING_SEL,TMIN,TMAX,TTYP);
end VAR_T;
--Figure 7.2 Timing control package.
entity OR2GV is
generic(TPLH,TPHL: TIME);
port(I1,I2: in BIT; O: out BIT);
end OR2GV;
architecture VAR_DEL of OR2GV is
begin
process(I1,I2)
variable OR_NEW,OR_OLD:BIT;
begin
OR_NEW := I1 or I2;
if OR_NEW = '1' and OR_OLD = '0' then
O <= OR_NEW after TPLH;
elsif OR_NEW = '0' and OR_OLD = '1' then
O <= OR_NEW after TPHL;
end if;
OR_OLD := OR_NEW;
end process;
end VAR_DEL;
--Figure 7.4 A variable delay OR gate model.
use work.DELAY.all;
architecture FUNC_DEL of OR2GV is
begin
process(I1,I2)
variable OR_NEW:BIT;
begin
OR_NEW := I1 or I2;
O <= OR_NEW after VAR_DEL(TPLH,TPHL,OR_NEW);
end process;
end FUNC_DEL;
--Figure 7.5 Using a function to select delays.
package DELAY is
type INT_VECT is array (NATURAL range <> ) of INTEGER;
function S_FANOUT(S: INT_VECT) return INTEGER;
subtype FINT is S_FANOUT INTEGER;
function VAR_DEL(TPLH,TPHL: TIME; FNEW: BIT) return TIME;
end DELAY;
package body DELAY is
function S_FANOUT(S: INT_VECT) return INTEGER is
variable SUM: INTEGER := 0;
begin
for I in S'RANGE loop
SUM := SUM + 1;
end loop;
return SUM;
end S_FANOUT;
function VAR_DEL(TPLH,TPHL: TIME; FNEW: BIT)
return TIME is
begin
if FNEW = '0' then
return TPHL;
else
return TPLH;
end if;
end VAR_DEL;
end DELAY;
-- (a)
use work.DELAY.all;
entity ORF is
generic(DEL_UNIT: TIME := 1 ns;I_LOAD: INTEGER := 1);
port(I1,I2: in BIT; I1L,I2L: out FINT;
O: out BIT; OL: in FINT);
end ORF;
architecture FANOUT of ORF is
signal DELAY: TIME:= 0 ns;
begin
process ----Input Load Process
begin
I1L <= I_LOAD;
I2L <= I_LOAD;
DELAY <= DEL_UNIT*OL;
wait;
end process;
O <= I1 or I2 after DELAY;
end FANOUT;
-- (b)
--Figure 7.7 Fanout sensitive delay model.
entity OR2GI is
generic(TPLH1,TPHL1,TPLH2,TPHL2,TPLHO,TPHLO: TIME);
port(I1,I2: in BIT; O: out BIT);
end OR2GI;
architecture VAR_DEL of OR2GI is
signal I1_D,I2_D: BIT;
begin
process(I1,I2)
begin
if I1'EVENT then
if I1 = '0' then
I1_D <= I1 after TPHL1;
else
I1_D <= I1 after TPLH1;
end if;
end if;
if I2'EVENT then
if I2 = '0' then
I2_D <= I2 after TPHL2;
else
I2_D <= I2 after TPLH2;
end if;
end if;
end process;
process(I1_D,I2_D)
variable OR_NEW,OR_OLD:BIT;
begin
OR_NEW := I1_D or I2_D;
if OR_NEW = '1' and OR_OLD = '0' then
O <= OR_NEW after TPLHO;
elsif OR_NEW = '0' and OR_OLD = '1' then
O <= OR_NEW after TPHLO;
end if;
OR_OLD := OR_NEW;
end process;
end VAR_DEL;
--Figure 7.9 VHDL code for input delay model.
/* VITAL Model Output Code for Cell ONAND */
----- CELL ONAND -----
library IEEE;
use IEEE.STD_LOGIC_1164.all;
library IEEE;
use IEEE.VITAL_Timing.all;
-- entity declaration --
entity ONAND is
generic(
TimingChecksOn: Boolean := True;
InstancePath: STRING := "*";
Xon: Boolean := False;
MsgOn: Boolean := True;
tpd_A_Y : VitalDelayType01:=(0.123 ns, .450 ns);
tpd_B_Y : VitalDelayType01 := (0.123 ns, 0.450 ns);
tpd_C_Y : VitalDelayType01 := (0.123 ns, 0.450 ns);
tpd_D_Y : VitalDelayType01 := (0.180 ns, 0.530 ns);
tipd_A : VitalDelayType01 := (0.000 ns, 0.000 ns);
tipd_B : VitalDelayType01 := (0.000 ns, 0.000 ns);
tipd_C : VitalDelayType01 := (0.000 ns, 0.000 ns);
tipd_D : VitalDelayType01 := (0.000 ns,0.000 ns));
port(
Y : out STD_LOGIC;
A : in STD_LOGIC;
B : in STD_LOGIC;
C : in STD_LOGIC;
D : in STD_LOGIC);
attribute VITAL_LEVEL0 of ONAND : entity is TRUE;
end ONAND;
--Figure 7.17 Entity in VITAL model output code for cell ONAND.
library IEEE;
use IEEE.VITAL_Primitives.all;
library LIBVUOF;
use LIBVUOF.VTABLES.all;
architecture VITAL of ONAND is
attribute VITAL_LEVEL1 of VITAL : architecture is TRUE;
SIGNAL A_ipd : STD_ULOGIC := 'X';
SIGNAL B_ipd : STD_ULOGIC := 'X';
SIGNAL C_ipd : STD_ULOGIC := 'X';
SIGNAL D_ipd : STD_ULOGIC := 'X';
begin
-- INPUT PATH DELAYS
WireDelay : block
begin
VitalWireDelay (A_ipd, A, tipd_A);
VitalWireDelay (B_ipd, B, tipd_B);
VitalWireDelay (C_ipd, C, tipd_C);
VitalWireDelay (D_ipd, D, tipd_D);
end block;
-- BEHAVIOR SECTION
VITALBehavior : process (A_ipd, B_ipd, C_ipd, D_ipd)
-- functionality results
VARIABLE Results: STD_LOGIC_VECTOR(1 to 1):=(others => 'X');
ALIAS Y_zd : STD_LOGIC is Results(1);
-- output glitch detection variables
VARIABLE Y_GlitchData : VitalGlitchDataType;
begin
-- Functionality Section
Y_zd := (NOT ((D_ipd) AND ((B_ipd) OR (A_ipd) OR C_ipd))));
-- Path Delay Section
VitalPathDelay01 (
OutSignal => Y,
GlitchData => Y_GlitchData,
OutSignalName => "Y",
OutTemp => Y_zd,
Paths => (0 => (A_ipd'last_event, tpd_A_Y, TRUE),
1 => (B_ipd'last_event, tpd_B_Y, TRUE),
2 => (C_ipd'last_event, tpd_C_Y, TRUE),
3 => (D_ipd'last_event, tpd_D_Y, TRUE)),
Mode => OnDetect,
Xon => Xon,
MsgOn => MsgOn,
MsgSeverity => WARNING);
end process;
end VITAL;
configuration CFG_ONAND_VITAL of ONAND is
for VITAL
end for;
end CFG_ONAND_VITAL;
---Figure 7.18 Architecture in VITAL model output code for cell ONAND
use work.SYSTEM_4.all;
entity FFRS is
generic(FFDEL,SPIKE_WIDTH: TIME);
port(R,S: in MVL4; Q,QN: out MVL4);
end FFRS;
architecture BEHAV of FFRS is
begin
process(R,S)
variable R_LAST_EVT, S_LAST_EVT: TIME := 0 ns;
variable BOTH: BOOLEAN:= FALSE;
begin
-----------Check for X's and Z's on inputs
assert not(R='X') report "X on R" severity WARNING;
assert not(R='Z') report "Z on R" severity WARNING;
assert not(S='X') report "X on S" severity WARNING;
assert not(S='Z') report "Z on S" severity WARNING;
-------Spike Detection
assert (NOW = 0 NS) or ((NOW - R_LAST_EVT) > SPIKE_WIDTH)
report "Spike On R" severity WARNING;
R_LAST_EVT := NOW;
assert (NOW = 0 NS) or ((NOW - S_LAST_EVT) > SPIKE_WIDTH)
report "Spike On S" severity WARNING;
S_LAST_EVT := NOW;
-- Code continued on next page.
--Figure 7.19 RS flip-flop model.
--------Flip-Flop Operation
if R = '0' and S ='1' then
Q <= '1' after FFDEL;
QN <= '0' after FFDEL;
end if;
if R = '1' and S='0' then
Q <= '0' after FFDEL;
QN <= '1' after FFDEL;
end if;
assert not(R = '1' and S = '1') --Check for R and S
report "R and S Both 1" --Both '1'
severity WARNING
if R = '1' and S = '1' then
Q <= '0' after FFDEL;
QN <= '0' after FFDEL;
BOTH := TRUE;
end if;
if R /= '1' and S /= '1' and BOTH then --Previous
Q <= '0' after FFDEL; -- inputs were R=S='1'
QN <= '1' after FFDEL;
BOTH := FALSE;
end if;
end process;
end BEHAV;
---Figure 7.20 RS Flip-flop Model (continued).
package BIT_TYPES is
type BIT_CODE is ('0', '1', 'X', 'Z');
type BIT_CODE_VECTOR is array (Natural range <>)
of BIT_CODE;
type WEAKNESS_VALUE is range 0 to 255;
type WEAKNESS_VALUE_VECTOR is array (Natural range <>)
of WEAKNESS_VALUE;
type SWITCH_STATE is (mos_turn_off, mos_turn_on,
mos_turn_x);
procedure LATTICE_LUB(NEW_VALUE: inout BIT_CODE;
NEW_WEAKNESS: inout WEAKNESS_VALUE;
VALUE: in BIT_CODE;
WEAKNESS: in WEAKNESS_VALUE);
function NEW_NODE_WINS(NEW_VALUE: BIT_CODE;
NEW_WEAKNESS: WEAKNESS_VALUE;
OLD_VALUE: BIT_CODE;
OLD_WEAKNESS: WEAKNESS_VALUE)
return Boolean;
end BIT_TYPES;
--Figure 7.26 Switch network package.
use work.BIT_TYPES.all;
entity NSWITCH is
generic (CHANNEL_DEGRADATION: WEAKNESS_VALUE := 1);
port (GATE: in BIT_CODE;
SOURCE, DRAIN: inout BIT_CODE;
SOURCE_WEAKNESS, DRAIN_WEAKNESS: inout WEAKNESS_VALUE);
end NSWITCH;
architecture ARCH of NSWITCH is
signal STATE: SWITCH_STATE;
begin
process (GATE, SOURCE, DRAIN, STATE)
begin
if (GATE'event) then
case (GATE) is
when '0' => STATE <= mos_turn_off;
when '1' => STATE <= mos_turn_on;
when others => STATE <= mos_turn_x;
end case;
end if;
case (STATE) is
when mos_turn_off => -- infinite weakness
DRAIN <= 'X';
DRAIN_WEAKNESS <= WEAKNESS_VALUE'high;
SOURCE <= 'X';
SOURCE_WEAKNESS <= WEAKNESS_VALUE'high;
when mos_turn_on =>
DRAIN <= SOURCE;
DRAIN_WEAKNESS <= SOURCE_WEAKNESS + CHANNEL_DEGRADATION;
SOURCE <= DRAIN;
SOURCE_WEAKNESS <= DRAIN_WEAKNESS + CHANNEL_DEGRADATION;
when mos_turn_x =>
DRAIN <= 'X';
DRAIN_WEAKNESS <= SOURCE_WEAKNESS + CHANNEL_DEGRADATION;
SOURCE <= 'X';
SOURCE_WEAKNESS <= DRAIN_WEAKNESS + CHANNEL_DEGRADATION;
end case;
end process;
end ARCH;
--Figure 7.27 Switch model.
use work.BIT_TYPES.all;
entity IDEAL_NODE is
port (STATES: inout BIT_CODE_VECTOR;
STRENGTHS: inout WEAKNESS_VALUE_VECTOR);
end IDEAL_NODE;
architecture ARCH of IDEAL_NODE is
begin
process (STATES, STRENGTHS)
variable NODE_VALUE, RESULT_VALUE: BIT_CODE;
variable NODE_WEAKNESS, RESULT_WEAKNESS: WEAKNESS_VALUE;
begin
RESULT_VALUE := 'X'; -- infinite weakness
RESULT_WEAKNESS := WEAKNESS_VALUE'high;
for i in STATES'range loop
LATTICE_LUB(RESULT_VALUE, RESULT_WEAKNESS, STATES(i),
STRENGTHS(i));
end loop;
if (NEW_NODE_WINS(RESULT_VALUE, RESULT_WEAKNESS,
NODE_VALUE, NODE_WEAKNESS)) then
for i in STATES'range loop
if (NEW_NODE_WINS(RESULT_VALUE, RESULT_WEAKNESS,
STATES(i), STRENGTHS(i))) then
STATES(i) <= RESULT_VALUE;
STRENGTHS(i) <= RESULT_WEAKNESS;
end if;
end loop;
end if;
NODE_VALUE := RESULT_VALUE;
NODE_WEAKNESS := RESULT_WEAKNESS;
end process;
end ARCH;
--Figure 7.28 Node model.
---------------------------------------------------------
--Primitive name: ORGATE
--Purpose: An OR gate for multiple value logic STD_LOGIC,
-- N inputs, 1 output.
--(see package IEEE.STD_LOGIC_1164 for truth table)
---------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_MISC.all;
entity ORGATE is
generic (N: Positive := 2;-- number of inputs
tLH: Time := 0 ns; -- rise inertial delay
tHL: Time := 0 ns; -- fall inertial delay
STRN: STRENGTH := STRN_X01);-- output strength
port (INPUT: in STD_LOGIC_VECTOR (1 to N);-- inputs
OUTPUT: out STD_LOGIC); -- output
end ORGATE;
-- Model is continued on next page.
--Figure 7.34 OR gate model.
architecture A of ORGATE is
signal CURRENTSTATE: STD_LOGIC := 'U';
subtype TWOBIT is STD_LOGIC_VECTOR (0 to 1);
begin
P: process
variable NEXTSTATE: STD_LOGIC;
variable DELTA: Time;
variable NEXT_ASSIGN_VAL: STD_LOGIC;
begin
-- evaluate logical function
NEXTSTATE := '0';
for i in INPUT'range loop
NEXTSTATE := INPUT(i) or NEXTSTATE;
exit when NEXTSTATE = '1';
end loop;
NEXTSTATE := STRENGTH_MAP(NEXTSTATE, STRN);
if (NEXTSTATE /= NEXT_ASSIGN_VAL) then
-- compute delay
case TWOBIT'(CURRENTSTATE & NEXTSTATE) is
when "UU"|"UX"|"UZ"|"UW"|"U-"|"XU"|"XX"|"XZ"|"XW"|
"X-"|"ZU"|"ZX"|"ZZ"|"ZW"|"Z-"|"WU"|"WX"|"WZ"|
"WW"|"W-"|"-U"|"-X"|"-Z"|"-W"|"--"|"00"|"0L"|
"LL"|"L0"|"11"|"1H"|"HH"|"H1"
=> DELTA := 0 ns;
when "U1"|"UH"|"X1"|"XH"|"Z1"|"ZH"|"W1"|"WH"|"-1"|
"-H"|"0U"|"0X"|"01"|"0Z"|"0W"|"0H"|"0-"|"LU"|
"LX"|"L1"|"LZ"|"LW"|"LH"|"L-"
=> DELTA := tLH;
when others => DELTA := tHL;
end case;
-- assign new value after internal delay
CURRENTSTATE <= NEXTSTATE after DELTA;
OUTPUT <= NEXTSTATE after DELTA;
NEXT_ASSIGN_VAL := NEXTSTATE;
end if;
-- wait for signal changes
wait on INPUT;
end process P;
end A;
--Figure 7.35 OR gate model (continued).
entity CTR is
port(RESET,RUN,COUNT: in BIT;
CNT: inout BIT_VECTOR(2 downto 0));
end CTR;
architecture STRUCTB of CTR is
signal CLK: BIT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -