Upload
others
View
6
Download
0
Embed Size (px)
Citation preview
Lecture 10 – Miscellaneous issues
Erno Salminen, Fall 2014 –Spring 2015
TIE-50206 Logic synthesis
Contents
2
Tri-state logic, high-impedance state ’Z’
Variables versus signals in VHDL
The notorius latches
Several synthesis examples here and there
Example codes can downloaded from the course web site
About exam
3
Like this, så här
For-loop in HDL: known bounds, parallel HW, single cycle (orcomb delay)
RTL vs structural is about style: if/for/case vs. instantiations, not necessarily about the abstraction level Usually structural model connects RTL or other structural blocks
together Philosphocally structural could also use basic gates, but that is
commonly dubbed as gatelevel, and that is below RTL Mark signal transitions clearly and use lines for 1-bit signals
Birectional I/O with tri-state logic
Simplex, half-duplex, (full) duplex 3 basic types of communication channels
Channel control Only two communicating blocks in the simplest case
During transfer master initiates transfers slave accepts transfers and responds to them
In some cases, a certain block can act both as master and slave
Many buses are shared multimaster buses shared = more than 2 units multimaster = more than 1 master arbitration mechanism decides which has the ownership
Bidirectional IO port Three-state buffer allows output
ports to havea) logical 0 or 1 valueb) hi-Z (high-impedance), aka. tri-state
In high-impedance state, the buffer’s input is not connected to its output
Output ”floats” Other blocks can drive ita) Pull-up/down resistors are often used
Buffer is ”stronger” than pull-up
b) Hold circuit keeps the last value
The output_enable signal ’oe’ selects between conducting and Hi-Z states
output_enable
data_in
data_out
oe = 0
Hi-Z
oe = 1
conduct
Vdd
R
X
X
X
Bidirectional IO port (2) Only 1 output can be drive at any time to avoid
short-circuit! Bus protocol defines arbitration policy How to select current master (driver) block
Note that here the tri-state enable TRISn is active low.
Fig. R. Reese
Tri-state just in I/O, not on chip Three-state should be used only in I/O pins
Difficult to test that only driver is active at any time Pull-up/Bus keeper logic problematic Simplifies PCB design (less components and wires)
Not inside chip! Use multiplexers instead Logic is cheap – verification is expensive
”we consider multiplexer-based buses to be the only acceptablearchitecture for on-chip interconnect. Tri-state buses should never beused on chip” Keating, Bricaud, Reuse Methodology Manual
Conditions (such as if-else and case) are synthesized differentlywith tri-state logic! There won’t be a multiplexer but a special tri-state buffer Note also that tri-state buffer is after DFF in synchronous logic
Tri-state logic in VHDL High-impedance state denoted with ’Z’
process (...) -- both seq. and comb. possiblebegin ...if (...)
data_out <= new_value;else
data_out <= (others => ’Z’)
output_enable
data_in
data_out
output_enable
data_in
data_out
Sequential process (clk, rst_n) Combinatorial process (new_value,...)
Synthesis tool generates
output_enable from the if-condition
X X
Note on following examples These simple examples have three purposes
1. Show how to implement tri-state logic in VHDL2. Show the schematic created by synthesis tool3. Show the resulting wave form
After this course, you should be able Understand the correlation between1) HDL and HW (all constructs are not synthesizable!)2) HDL and simulator output You can perform simple simulation and synthesis ”in your
head”
Example: tri_state1.vhdreg_z: process (clk, rst_n)begin if rst_n = '0' then test0_out <= '0';
elsif clk'event and clk = '1' then
if ctrl_in = '1' thentest0_out <= data_in;
elsetest0_out <= 'Z';
end if; end if;
end process reg_z;
comb_z: process (ctrl_in)beginif ctrl_in = '1' thentest1_out <= '1';
elsetest1_out <= 'Z';
end if; end process comb_z;
tri_state1 – HW (OK) enable logic (DFF) for the tri-state buffer
inverting tri-state buffer,
conducts when its enable=1
output port
input port
actual register for test0_out
logic from sequential process
logic from combinatorial process
use inverted output with this tri-state buf
general signal direction
Wave form of tb_tri_state1
Sync.output0 is ’0’ during reset, but comb. output1 is ’Z’. Both outputs are
’Z’ when ctrl=’0’
Sync. output0 follows the input
with 1 cycle delay, comb. output1 has here a constant ’1’
Output0 follows the input, output1 hass
constant ’1’
Special values ’Z’ and ’U’ propagated to
output0 in simulation (not in real HW)
Both outputs are ’Z’ when ctrl=’0’
Mismatch between tri-state logic simulation and synthesis -11. Propagation ’Z’ cannot propagate through flip-flop in real circuit
’Z’ cannot propagate through real logic gates
Physical DFF’s or gate’s output will be undefined ifits input is ’Z’ (=floating somewhere between GND and VDD) Same notes apply ’U’, ’X’, ’H’, ’L’, and ’-’
’Z’ must be assigned to output port directly
tri_state2.vhdreg_z _ process -- similar to previous, but-- intermediate signal test0_r used instead-- of output. Registers gets either data_in or ’Z’test0_out <= test0_r;
reg_z_bad: process (clk, rst_n)begin -- process reg_z
if rst_n = '0' then test1_out <= '0';
elsif clk'event and clk = '1' then test1_out <= test0_r;
end if;end process reg_z_bad;
comb_z_bad: process (test0_r, enable_in)begin -- process comb_z
test2_out <= test0_r and enable_in;end process comb_z_bad;
HW from tri_state2.vhd (BAD)logic from process reg_z.
So far, so good...
DFF cannot propagate ’Z’ from its input to the output
AND gate cannot propagate ’Z’ from its input to the output
ok
Tri-state buffer is in the middle of logic and not directly on the outputs. paha paha
Mismatch between tri-state logic simulation and synthesis -22. Readingif a_in /= ”ZZZ” then
-- may work in simulation but makes no sense in synthesis
There is not any logic circuit that can detect if input is ’Z’ Depending on technology and phase of of the moon, ’Z’ at input will
be as interpreted as ’0’ or ’1’ One cannot predict the result!
Same notes apply ’U’, ’X’, ’H’, ’L’, and ’-’
Logic must read some control signal to see if data is valid
non-deterministic value from ANDa
’0’
’Z’
b
a ’Z’
b
’0’
1
0’something_else’
Example: HW using the value of a which might be ’Z’:
tri_state3.vhdtest0_out <= std_logic_vector(accu0_r);test1_out <= std_logic_vector(accu1_r);
test_z_bad : process (clk, rst_n)
begin if rst_n = '0' then
accu0_r <= (others => '0');
elsif clk'event and clk = '1' then
if data_in /= "ZZZZ" thenaccu0_r <= accu0_r
+ signed(data_in);end if;
end if;end process test_z_bad;
read_ctrl_ok : process (clk, rst_n)
begin -- process reg_z if rst_n = '0' then
accu1_r <= (others => '0');
elsif clk'event and clk = '1' then
if ctrl_in = '1' thenaccu1_r <= accu1_r
+ signed(data_in);end if;
end if;end process read_ctrl_ok;
tri_state3 HW in Design Vision
Error: Illegal use of tri-state variable (ELAB-306)*** Presto compilation terminated with 1 errors. ***Had to comment out the process test_z_bad! Hence, no logic is synthesized for that
Sidenote: This schematic is harder to read ”Wide” data (although just 4 bits...) No hierarchy ( 4-bit register is spread around Logic for multiplexers and adders combined Hierachy can be added by grouping cells together
test0_out has no value at all.
test1_out is fine
tri_state3 HW on Quartus
accu0_r updated if
data_in is not ZERO! accu1_r
updated if ctrl_in is not
zero as expected.
4-bit adder
Hierarchy visible, which is nice.
Rather useless XORs…
Tri-state summary Use for I/O between chips Just for chip’s I/O pins and not between logic modules on chip
Usually with bidirectional I/O Some cases ’Z’ assigned to regular unidirectional output E.g. many slave outputs connected to single input at master, such as
multiple memories connected to same CPU Third signal state – high-impedance Lets the signal voltage float and some other device may drive it Assigned by writing ’Z’ to the signal/port Cannot be propagated through real DFFs or gates
Presence of ’Z’ cannot be tested directly Must use separate valid signal to see when signal can be read safely
Simulation and real HW do not always match!
About VHDL variables
Variables in VHDL Variables allow a more sequential style of "programming" It seems alluring option BUT: a death cap also looks nice but is venomous inside…
For communication between processes, only signals can be used There are so called shared variables but we won’t use them.
With TEXTIO, variables are must In procedures and functions, variables can be used Certain structures are best captured with variables The problems are related to synthesis and not seeing the
values in simulator
Variables vs. signals In contrast to signals, the order of reading/assigning variables is
important. Remember:
1. The value assigned to a signal can be read back only after at least a delta cycle
2. Another way of looking at it (in case of a flip-flop): a) a signal allows to read only the Q output of a flipflop
b) a variable also makes it possible to read the D input of a flipflop.
incr : process (clk, rst_n)variable sum_v...
beginif rst_n...elsif rising_edge(clk) then
sum_v := sum_r + 1;sum_r <= sum_v;if sum_v =...
end process ;
sum_rD Q+
+1
if...sum_v
Relation between HDL and HW Given the usual RTL paradigm, the relationship between
1. VHDL signals and the hardware they represent can be explained rather easily
2. VHDL variables and the hardware they represent (or don't!) is much subtler.
Note! Not the variables themselves, but references to them imply storage or not (i.e. thus a register or not);
The same variable name may represent a combinatorial value in one reference, and a register value in another
VHDLHW: Combinatorial process1. Signal assignment:
Must get a value for every execution of the process. OK Otherwise, it will create a latch
Recommendations: Assign signals in every if-brach or give them default value and override it later It is not recommended to read a value that is written in the same comb. process,
otherwise, signal must be on sensitivity list and process must iterate Write a complete sensitivity list
2. Variable assignment: Implies combinational logic when always written before read. OK. Must get a value for every execution of the process
Otherwise, it will create a latch just like s signal would
If read before written, behavior in synthesis may vary
Pretty similar behavior between signals and variables
comb
VHDLHW: Sequential process1. Signal assignment: Always implies a register
Registers are created for all signal and port assignments unless there is a redundancy that can be merged with another register
Very simple! Easy to remember and analyze
2. Variable assignment:a) Implies combinational logic when always written before read
Good! See earlier example on sum_v
b) Implies a register if variable read before writtenc) Alternately implies a register if variable has a life time May be hard to figure out which variables imply registers
Some will imply many, some will imply one, some will imply none The designer does not master the HW that he/she is designing
Signals and variables differ clearly Their timing in simulator might look identical, but behaviors differ…
comb
Variables in comb. process (var1.vhd)-- Invert the input signalcomb_ok : process (a_in)variable inv_v : std_logic;
begin -- process combinv_v := not a_in;test0_out <= inv_v;
end process comb_ok;
-- Stores the prev value of a_inseq_help : process (clk, rst_n)begin -- process seq_helpif rst_n = '0' then
tmp_r <= '0';elsif clk'event and clk = '1'
thentmp_r <= a_in;
end if;end process seq_help;
-- Tries to indicate if input -- has been high for more than -- 1 cycle
comb_bad: process (a_in, tmp_r)variable last_a_v : std_logic;
begin -- process comb_bad
if tmp_r = a_in thenlast_a_v := a_in;
-- else branch missingend if; test1_out <= last_a_v;
end process comb_bad;
Var.comb.proc: resulting HW (var1.vhd)
variable inv_v in comb. process produces comb. logic. Good!
signal tmp_r in seq. process produces a DFF. Good!
variable last_a_v in comb. process produces a latch. Bad! However, a
signal would be equally bad.
Eq.comparison in if-clause in comb.
process produces comb. logic. Good!
Wave form of var1.vhd
Latched valueComb ok
Reg ok
Output test1 falls when register tmp_r has also
gone low – not immediately when a_in changes
VHDL code of var2seq_ok : process (clk, rst_n)variable comb_v : std_logic;
begin -- process seq_okif rst_n = '0' then test0_r <= '0';test1_out <= '0';test2_out <= '0'; -- reset values are ok
elsif clk'event and clk = '1' then comb_v := a_in;test0_r <= comb_v;
test1_out <= comb_v and b_in;test2_out <= test0_r and b_in;
end if;end process seq_ok;test0_out <= test0_r;
Wave form of var2.vhd
ok
Value of comb_vseems identical to test0_r afterreset…
Outputs test1 and test2 are not identical although they seem to read identical values! :-0
AND’s
Simulated timing of comb_v does not matchreal HW… Timing of comb_v should be identical to a_in
HW of var2.vhdvar. comb_v
means this node, flip-flops’s D-input
signal test0_r in seq. process produces
DFF. Good!
output test0_out follows DFF test0_r
directly. Good!reading the var: comb path from input to
here. Good.
reading the signal: value a comes from
DFF. Good.
signal test0_r means this node, flip-flops Q-output, so it’s not the
same as comb_v
a AND b(remember de Morgan)
test1 and test2 are DFFs as
expected
VHDL code of var3seq_baddish : process (clk, rst_n)
variable dff_v : std_logic;begin -- process seq_baddish
if rst_n = '0' thentest0_out <= '0'; -- value comes from vartest1_r <= '0'; -- value comes from signal dff_v := '0';
elsif clk'event and clk = '1' thenif a_in = '1' then
dff_v := not dff_v;test1_r <= not test1_r;
end if; test0_out <= dff_v;
end if;end process seq_baddish;test1_out <= test1_r; -- just a wire
Invert the output every time when input ais ’1’
Wave form of var3.vhd
Identical outputs. So far, so good...
HW of var3.vhdXOR does
inversion when the other input is ’1’
Output driven by signal
Output driven by variable & signal
Extra DFF due to variable. Semi-kääk.
variable means this circuit node
Luckily, the ouputs have identical timing. So, the drawback from variable is the minor area overhead due to extra DFF.
When to use variables When they simplify non-synthesizable design (=testbench)
notably
Especially, when modeling memory (RAM) Because variables do not have an event queue associated, their
space requirement (memory footprint on your workstation/PC) is about ten times smaller than the equivalent signal
For large RAMs this could prevent running out of memory
If you are absolutely certain - and can assure everyone around you - that they simplify synthesizable code
About latches
level-sensitive
edge-triggered
Latches and flip-flops Two categories of memory
elements1. level-sensitive - latches
2. edge-triggered – flip-flops
Various types Some are unnecessarily
difficult to use
Edge-triggered behaviorsimplifies timing analysis
Simple data flip-flop(DFF) is superior and The others are obsolete and
should be avoided D Q
R Q
S
J Q
K
D QD Q
C
JK latch
SR latch
D latch
T Q
T flip-flop
D flip-flop
useful?
no
no
no
rarely
Why are D-latches good? Compared to edge triggered flip-flops Less area Less power Allow ”cycle-stealing/time-borrowing”
Hence, latches were/are used in real designs But that is intentional and done by experienced professionals Usually, only in full-custom design (Intel and AMD but not too
may others), like CPU pipeline
However, most latches in student designs are unintentionaland therefore very harmful
(senior full-custom ASIC designers)
Why are latches evil?1. They are nightmare for Static Timing Analysis tools Use of STA tools is mandatory
2. They are bad for Design for Test tools Use of DFT tools is mandatory for ASIC
3. There aren’t any latches in FPGAs One may emulate them with LUT and flip-flops...
4. Glitches in the enable pin of the latches cause improper functioning. Glitch-free logic is hard to synthesize
5. Latches in feedback loops may create unintentional oscillator
Example latch usage We can connect some latches, acting as memory, to an ALU.
Let’s say these latches contain some value that we want to increment. The ALU should read the current latch value Q via input X It applies the increment operation G = X+1 The incremented value is stored back into the latches.
At this point, we have to stop the cycle, so the latch value doesn’t get incremented again by accident.
One convenient way to break the loop is to disable the latches by driving en=0
+1ALU
SX
G
LatchesD
Qen
[https://agora.cs.illinois.edu/download/attachments/19924352/12-Latches.ppt?version=2]
The problem with latches
The problem is exactly when to disable the latches. You have to wait long enough for the ALU to produce its output, but no longer. But different ALU operations have different delays. For instance, arithmetic
operations might go through an adder, whereas logical operations don’t.
Changing the ALU implementation, such as using a carry-lookahead adder instead of a ripple-carry adder, also affects the delay.
In general, it’s very difficult to know how long operations take, and how long latches should be enabled for If you take the max. delay, you could as well use regular edge-triggered DFF
+1ALU
SX
G
LatchesD
Qen
enable generation
Latch timing example
[Ray Frey, http://zebu.uoregon.edu/~rayfrey/432/notes3.pdf]
Setup and hold w.r.t. falling edge of CLK
CLK pulse width must be larger than certain min. value
Ambiguity regarding exactly when the D input gets latched into Q
If a transition in D occurs sometime during a clock HIGH, what will occur?
The answer will depend upon the characteristics of the particular electronics being used
This lack of clarity is often unacceptable
transparent latched
=D latch
Inferred latch exampleprocess(enable, data_in) – so far, so goodbegin
if (enable='1') then...badass <= data_in; -- so far, so good...
-- else branch missing! so bad end if;end process; Combinational process (=logic), but the signal “badass" does not get a
value assigned in every possible branch Logic will have to ”remember” the last value when enable=’0’ Common mistake
(Not) inferring latches1. Latches are inferred by branch statements (if-elsif) which
are not be completely specified in combinatorial process To avoid a Latch being developed 1. Assign an output for all possible input conditions 2. Use an "else" statement instead of an "elsif" in the final
branch of an "if" to avoid a latch 3. You may assign default values at the beginning of a process to
avoid an inferred latch
2. When the "event" statement is missing in sequential process
(Not) inferring latches (2) http://www.doulos.com/knowhow/vhdl_designers_guide/tips/
avoid_synthesizing_unwanted_latches/
http://www.nalanda.nitc.ac.in/industry/appnotes/xilinx/documents/techdocs/3583.htm
http://www.altera.com/support/examples/vhdl/vhd-prevent-latch.html
http://www.altera.com/literature/hb/qts/qts_qii51007.pdf
http://www.eetimes.com/editorial/1997/test9708.html
Conclusions Be careful with reset
Be careful with clocks
Be careful with ’Z’
Avoid variables in most cases
Avoid latches in practically all cases