160 likes | 282 Views
Reconfigurable Computing - Type conversions and the standard libraries. John Morris Chung-Ang University The University of Auckland. ‘Iolanthe’ at 13 knots on Cockburn Sound, Western Australia. Arithmetic in a programming language. VHDL is like a general purpose programming language!
E N D
Reconfigurable Computing -Type conversions and the standard libraries John Morris Chung-Ang University The University of Auckland ‘Iolanthe’ at 13 knots on Cockburn Sound, Western Australia
Arithmetic in a programming language • VHDL is like a general purpose programming language! • You should be able to write things like • c = a + b; c = a – b; • IF a = b THEN … END IF; • IF a < b THEN … END IF; • and even .. • C = a * b; • D = a / b; • without having to implement adders, subtracters, comparators, … explicitly! • There is a standard library • std_logic_arith which defines operators: +, -, ABS, *, <, <=, >, >=, =, /=, SHL, SHR • So you can write • c = a + b; cnt = cnt – 1; … if you get the types right!! • VHDL is strongly typed, so this can sometimes be painful!! • The advantage is that, when you do get it to compile, it’s more likely to generate a correct circuit!
std_logic_arith • Reading the package header for this can be somewhat daunting … The semicolons should be at the end of each line! This error brought to you by Microsoft and the PowerPoint team! library IEEE; use IEEE.std_logic_1164.ALL; PACKAGE std_logic_arith is type UNSIGNED is array (NATURAL range <>) of STD_LOGIC; type SIGNED is array (NATURAL range <>) of STD_LOGIC; subtype SMALL_INT is INTEGER range 0 to 1; function "+"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED; function "+"(L: SIGNED; R: SIGNED) return SIGNED; function "+"(L: UNSIGNED; R: SIGNED) return SIGNED; function "+"(L: SIGNED; R: UNSIGNED) return SIGNED; function "+"(L: UNSIGNED; R: INTEGER) return UNSIGNED; function "+"(L: INTEGER; R: UNSIGNED) return UNSIGNED; function "+"(L: SIGNED; R: INTEGER) return SIGNED; function "+"(L: INTEGER; R: SIGNED) return SIGNED; function "+"(L: UNSIGNED; R: STD_ULOGIC) return UNSIGNED; function "+"(L: STD_ULOGIC; R: UNSIGNED) return UNSIGNED; function "+"(L: SIGNED; R: STD_ULOGIC) return SIGNED; function "+"(L: STD_ULOGIC; R: SIGNED) return SIGNED; The library is a VHDL PACKAGE (as most are) Note that we have three new types here: UNSIGNED, SIGNED and SMALL_INT … and MANY definitions of “+”!!! These are necessary because of thestrong typing – but they allow you to write a variety of expressions! U, v, w: unsigned( 0 TO n);s, r, t: signed( 0 TO n);i, j, k: integer;
std_logic_arith • Reading the package header for this can be somewhat daunting … The semicolons should be at the end of each line! This error brought to you by Microsoft and the PowerPoint team! library IEEE; use IEEE.std_logic_1164.ALL; PACKAGE std_logic_arith is type UNSIGNED is array (NATURAL range <>) of STD_LOGIC; type SIGNED is array (NATURAL range <>) of STD_LOGIC; subtype SMALL_INT is INTEGER range 0 to 1; function "+"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED; function "+"(L: SIGNED; R: SIGNED) return SIGNED; function "+"(L: UNSIGNED; R: SIGNED) return SIGNED; function "+"(L: SIGNED; R: UNSIGNED) return SIGNED; function "+"(L: UNSIGNED; R: INTEGER) return UNSIGNED; function "+"(L: INTEGER; R: UNSIGNED) return UNSIGNED; function "+"(L: SIGNED; R: INTEGER) return SIGNED; function "+"(L: INTEGER; R: SIGNED) return SIGNED; function "+"(L: UNSIGNED; R: STD_ULOGIC) return UNSIGNED; function "+"(L: STD_ULOGIC; R: UNSIGNED) return UNSIGNED; function "+"(L: SIGNED; R: STD_ULOGIC) return SIGNED; function "+"(L: STD_ULOGIC; R: SIGNED) return SIGNED; The library is a VHDL PACKAGE (as most are) u, v, w: unsigned( 0 TO n);s, r, t: signed( 0 TO n);i, j, k: integer; u <= v + w;s <= r + t;s <= u + r; S <= r + u;u <= v + j; u <= j + v;s <= r + j; …
std_logic_arith • To get things into the right type, you need to use conversion functions • These (+more!) appear in std_logic_arith ;function CONV_INTEGER(ARG: UNSIGNED) return INTEGER function CONV_INTEGER(ARG: SIGNED) return INTEGER; function CONV_INTEGER(ARG: STD_ULOGIC) return INTEGER; function CONV_UNSIGNED(ARG: INTEGER; SIZE: INTEGER) return UNSIGNED; function CONV_UNSIGNED(ARG: UNSIGNED; SIZE: INTEGER) return UNSIGNED; function CONV_UNSIGNED(ARG: SIGNED; SIZE: INTEGER) return UNSIGNED; function CONV_UNSIGNED(ARG: STD_ULOGIC; SIZE: INTEGER) return UNSIGNED; function CONV_SIGNED(ARG: INTEGER; SIZE: INTEGER) return SIGNED; function CONV_SIGNED(ARG: UNSIGNED; SIZE: INTEGER) return SIGNED; function CONV_SIGNED(ARG: SIGNED; SIZE: INTEGER) return SIGNED; function CONV_SIGNED(ARG: STD_ULOGIC; SIZE: INTEGER) return SIGNED; return STD_LOGIC_VECTOR;)function CONV_STD_LOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGERfunction function CONV_STD_LOGIC_VECTOR(ARG: UNSIGNED; size: integer ) return std_logic_vector;
General Type Conversion • When the types are compatible, you can cast a type like this: • For example, signed and std_logic_vector are essentially the same,so this works: a, b : std_logic_vector; s: signed; s <= signed( a ); s <= signed(a) + signed(b);
Typical FPGA Architecture • Logic blocks embedded in a ‘sea’ of connectionresources • CLB = logic blockIOB = I/O bufferPSM = programmable switch matrix • Interconnections critical • Transmission gates on paths • Flexibility • Connect any LB to any other • but • Much slower than connections within a logic block • Much slower than long lines on an ASIC • Aside: • This is a ‘universal’ problem - not restricted to FPGAs! • Applies to • • custom VLSI, • • ASICs, • • systems, • • parallel processors • Small transistors high speed high density long, wide datapaths
Logic Blocks • Combination of • And-or arrayorLook-Up-Table (LUT) • Flip-flops • Multiplexors • General aim • Arbitrary boolean function of several variables • Storage • Adders are critical • All modern FPGAs have‘fast carry logic’ • High speed lines connectingLBs directly • Very fast ripple carry adders
an-1 a1 bn-1 b1 an-2 a0 bn-2 b0 FA FA FA FA cout cout cin cin cout cout cin cin sn-1 s1 sn-2 s0 carryout Ripple Carry Adder • The simplest and most well known adder • Time to complete • n x propagation delay( FA: (a or b) carry ) • We can do better than this - using one of many known better structures • but • What are the advantages of a ripple carry adder? • Small • Regular • Fits easily into a 2-D layout! Very important in packing circuitry into fixed 2-D layout of an FPGA!
an-1 a1 a3 bn-1 b3 b1 an-2 a2 a0 bn-2 b2 b0 FA FA FA FA FA FA cout cout cout cin cin cin cout cout cout cin cin cin sn-1 s1 s3 sn-2 s2 s0 carryout LB LB LB Ripple Carry Adders • Ripple carry adder performance is limited by propagation of carries But these signals would need to be carried by the generalrouting resources (slow!) (In fact, you can’t fit a 2-bit adder with carry out in a CLB because there aren’t enough outputs! A 2-bit adder fits in a Xilinx CLB (enough logic for 5 inputs and 2 outputs) The fast carry logic provides special (low R) lines for carry-in and carry-out fast adder with 2 bits/CLB
‘Fast Carry’ Logic • Critical delay • Transmission of carry out from one logic block to the next • Solution (most modern FPGAs) • ‘Fast carry’ logic • Special paths between logic blocks used specifically for carry out • Very fast ripple carry adders! • More sophisticated adders? • Carry select • Uses ripple carry blocks - so can use fast carry logic • Should be faster for wide datapaths? • Carry lookahead • Uses large amounts of logic and multiple logic blocks • Hard to make it faster for small adders!
Carry Select Adder a4-7 b4-7 0 cin a0-3 cout7 b0-3 n-bit Ripple Carry Adder sum04-7 cout3 n-bit Ripple Carry Adder 1 b4-7 cout7 n-bit Ripple Carry Adder sum0-3 sum14-7 ‘Standard’ n-bit ripple carry adders n = any suitable value 0 1 0 1 Here we build an 8-bit adder from 4-bit blocks carry sum4-7
These two blocks ‘speculate’ on the value of cout3 This block adds the 4 low order bits After 4*tpd it will produce a carry out Carry Select Adder a4-7 b4-7 0 cin a0-3 cout7 b0-3 n-bit Ripple Carry Adder sum04-7 cout3 n-bit Ripple Carry Adder 1 b4-7 cout7 n-bit Ripple Carry Adder sum0-3 sum14-7 One assumes it will be 0 the other assumes 1 0 1 0 1 carry sum4-7
This block adds the 4 low order bits After 4*tpd it will produce a carry out Carry Select Adder • After 4*tpd we will have: • sum0-3 (final sum bits) • cout3 (from low order block) • sum04-7 • cout07 (from block assuming 0 cin) • sum14-7 • cout17 (from block assuming 1 cin) a4-7 b4-7 0 cin a0-3 cout7 b0-3 n-bit Ripple Carry Adder sum04-7 cout3 n-bit Ripple Carry Adder 1 b4-7 cout7 n-bit Ripple Carry Adder sum0-3 sum14-7 0 1 0 1 carry sum4-7
Carry Select Adder a4-7 b4-7 0 cin a0-3 cout7 b0-3 n-bit Ripple Carry Adder Cout3 selects correct sum4-7 and carry out sum04-7 cout3 n-bit Ripple Carry Adder 1 b4-7 cout7 n-bit Ripple Carry Adder sum0-3 sum14-7 0 1 0 1 All 8 bits + carry are available after 4*tpd(FA) + tpd(multiplexor) carry sum4-7
Carry Select Adder • This scheme can be generalized to any number of bits • Select a suitable block size (eg 4, 8) • Replicate all blocks except the first • One with cin = 0 • One with cin = 1 • Use final cout from preceding block to select correct set of outputs for current block