21 Aug 1996 ... Use of Synario for CPLD (FPGA) Implementation. Reference: ISP Synario System
Design Tutorial (Lattice Semiconductor). Acrobat (*.pdf) files ...
Use of Synario for CPLD (FPGA) Implementation Reference: ISP Synario System Design Tutorial (Lattice Semiconductor) Acrobat (*.pdf) files available These notes show summary of designs, but not detailed procedures First example: 2-input AND gate with buffered output (Directory: And-2)
Test vector -- used to simulate circuit c -- clock; x -- don’t care Right side is all don’t-care Original use of these is for establishing a standard result We use it only for simulation, thus the don’t-care module and2_vec; c,x = .c.,.x.; CK,A,B,OUT PIN; TEST_VECTORS ([CK,A,B]->[OUT]) [c,0,0]->[x]; [c,1,0]->[x]; [c,1,0]->[x]; [c,1,0]->[x];
[c,0,1]->[x]; [c,1,1]->[x]; [c,1,1]->[x]; [c,1,1]->[x]; [c,0,1]->[x]; [c,0,1]->[x]; [c,0,1]->[x]; [c,0,1]->[x]; END
Simulation output:
Fitting the Design to a Part Fitting the design, results in Jedec file for download Fitter report (excerpts): (is)pLSI Development System Plus Release 3.0.12, Aug 21 1996 15:26:43
2
Design Parameters ----------------IGNORE_FIXED_PIN: MAX_GLB_IN: MAX_GLB_OUT: OUTPUT_FORM: STRATEGY: TIMING_ANALYZER:
OFF 16 ((is)pLSI1000,(is)pLSI2000), 24((is)pLSI3000) 4 SIM AREA OFF
Design Specification -------------------Design: Part:
and2 ispLSI1016-80LJ44
... Pre-Route Design Statistics --------------------------Number of GLBs: Number of I/Os: Number of Nets:
1 3 3
Number of Free Inputs: 2 Number of Free Outputs: 1 Number of Free Three-States: 0 Number of Free Bidi’s: 0 Number of Locked Input IOCs: 0 Number of Locked DIs: 0 Number of Locked Outputs: 0 Number of Locked Three-States: 0 Number of Locked Bidi’s: 0 Number of CRIT Outputs: Number of Global OEs: Number of External Clocks:
0 0 1
GLB Utilization (Out of 16): I/O Utilization (Out of 36): 8% Net Utilization (Out of 100): ...
6% 3%
Pin Assignments Pin Name B CK
Pin Assignment 9 11
Pin Type, Pin Attribute
Input Clock Input
3
OUT A
15 16
Output Input
Modules Schematic can be used to define modules and do hierarchical designs (Directory: And-Mod) Use modules to make design more manageable Define 2-input AND gate to be a module (FILE->Matching Symbol) Create a new schematic using the symbol (ADD->Symbol to find the new symbol)
4
Now add an ABEL module also It has same function - 2-input AND gate Follow procedure in tutorial to create the ABEL module Schematic:
5
ABEL code: MODULE AndAbel "The ABEL source code for a 2-input AND gate TITLE ’2-Input AND Gate in Abel’ " Inputs CKAbel pin; AAbel pin; BAbel pin;
"System clock "A input "B input
" Output OutAbel pin; EQUATIONS OutAbel = AAbel & BAbel; END
Simulation:
6
Out1 and Out2 are not identical Related to warning message in ABEL compilation: Warning 3514:Signal ’CKAbel’ in module ’andabel’ floats so it is ignored. Clock isn’t used here Difference is that ABEL module is purely combinational Original schematic sent output through a register (D-flip-flop) Modified ABEL code to add register: MODULE AndAbel "The ABEL source code for a 2-input AND gate TITLE ’2-Input AND Gate in Abel’ " Inputs CKAbel pin; AAbel pin; BAbel pin;
"System clock "A input "B input
7
" Output OutAbel pin istype ’reg, buffer’; "Add the ’istype’ to make output registered EQUATIONS OutAbel.clk = CKAbel; OutAbel := AAbel & BAbel;
"Add this line to connect the clock " Use this form for registered output
END
Out1 and Out2 now agree:
Sequential Logic -- State Machines Build some examples towards unidirectional pulse decoder First Example: (Directory A-Count1) Simple sequence -- state0 -> state1 -> state2 ->state0 increment counter in state1 Counter is 3-bit 8
Schematic:
Abel code: MODULE dcd TITLE ’Single Channel Decoder - Rising Edge Only’ "Inputs AD clk
pin; "Pulse input pin;
"Outputs c0,c1,c2 pin istype ’reg, buffer’; "3-bit counter count = [c2..c0]; "Group variables for counter q1,q0 pin istype ’reg, buffer’; "State variables state_val = [q1,q0]; Equations [q1,q0].clk = clk; count.clk = clk; when (state_val == 0) then { state_val := 1; count := count.fb; } when (state_val == 1) then { state_val := 2; count := count + 1; } when (state_val == 2) then { state_val := 0; count := count.fb; } END
Notes: 9
This uses “informal” logic to construct state machine When statement valid in Equation section (Use If only in formal state machine, below) Behavior:
Formal state machine ABEL has a formal structure for constructing state machines ABEL code: MODULE dcd TITLE ’Single Channel Decoder - Rising Edge Only’ "This version uses a formal state machine "Inputs AD
pin; "Pulse input
10
clk
pin;
"Outputs c0,c1,c2 pin istype ’reg, buffer’; "3-bit counter count = [c2..c0]; "Group variables for counter q1,q0 pin istype ’reg, buffer’; "State variables sreg = [q1,q0]; "State Values A = 0; B = 1; C = 2; Equations [q1,q0].clk = clk; count.clk = clk; State_Diagram sreg; State A: count := count.fb; if (1) then B; State B: count := count + 1; if (1) then C; State C: count := count.fb; if (1) then A; END
Result is the same PWM Generator Using informal approach (Directory: PWM1-pld) Schematic:
11
ABEL code: MODULE pwm_gen " This is the ABEL source code for a PWM generator. The PWM uses an " 8-bit counter and a comparator. When the input signal is higher " than the counter value, the output will be high; when not it’s low. " Thus a duty cycle will appear at the output which is proportional " to the number at the input. " " Note that the use of the word ’pin’ here indicates a connection from " this block to the outside of this block; in general it does not " mean a physical pin on the chip being programmed. TITLE ’8-bit PWM Generator’ " Inputs clock pin; d7..d0 pin; duty = [d7..d0];
" System clock " Input pins " Group pins into a number for clarity
" Outputs pwm_out pin istype ’reg, buffer’;
" Pin for output
" Internal nodes for counting c7..c0 node istype ’reg, buffer’; " Define the nodes, then specify count = [c7..c0]; " how they’re grouped into a number Equations pwm_out.clk = clock; count.clk = clock;
" Where clock signal is connected " for each register or group of regs.
12
count := count + 1;
" Counter runs continuously
" These are the equations which cause the PWM signal to go high and low " at the correct times to produce the desired duty cycle when (pwm_out == 0) then pwm_out := (count == 0) & (duty != 0); else when (pwm_out == 1) then pwm_out := !((count == duty) & (duty != 255)); END
The Unidirectional decoder
a
a: input unc: unconditional
State C unc a’
State B count
State A
a
a’ Use the formal state machine Modify it for the decoder state diagram ABEL code: MODULE dcd TITLE ’Single Channel Decoder - Rising Edge Only’ "This version uses a formal state machine " This is actually the decoder! "Inputs AD clk
pin; "Pulse input pin;
"Outputs c0,c1,c2 pin istype ’reg, buffer’; "3-bit counter
13
count = [c2..c0]; "Group variables for counter q1,q0 pin istype ’reg, buffer’; "State variables sreg = [q1,q0]; "State Values A = 0; B = 1; C = 2; Equations [q1,q0].clk = clk; count.clk = clk; State_Diagram sreg; State A: "Input is low, waiting for high count := count.fb; if (AD) then B; else A; State B: "Increment counter then move on! count := count + 1; if (1) then C; State C: "Input is high, waiting for low count := count.fb; if (!AD) then A; else C; END
Test vector: Module dcd; c,x=.c.,.x.; Clock,A,Ct0,Ct1,Ct2,q0,q1 pin; Test_Vectors ([Clock,A]->[Ct0,Ct1,Ct2,q0,q1]) [c,0]->[x,x,x,x,x]; [c,0]->[x,x,x,x,x]; [c,1]->[x,x,x,x,x]; [c,1]->[x,x,x,x,x]; [c,0]->[x,x,x,x,x]; [c,0]->[x,x,x,x,x]; [c,1]->[x,x,x,x,x]; [c,1]->[x,x,x,x,x]; [c,1]->[x,x,x,x,x]; [c,0]->[x,x,x,x,x]; [c,0]->[x,x,x,x,x]; [c,1]->[x,x,x,x,x]; [c,1]->[x,x,x,x,x]; [c,1]->[x,x,x,x,x];
14
[c,0]->[x,x,x,x,x]; END
Result:
Potential problem -- power-up state Examine this case:
15
Note that there is an immediate count Initial value of input is 1 Should this happen? Add extra state to determine where to start (Directory A-Count3) a: input unc: unconditional a a State C unc State D power-up
a’
State B count
State A
a
a’ 16
ABEL code: MODULE dcd TITLE ’Single Channel Decoder - Rising Edge Only’ "This version uses a formal state machine " This is actually the decoder! "Inputs AD clk
pin; "Pulse input pin;
"Outputs c0,c1,c2 pin istype ’reg, buffer’; "3-bit counter count = [c2..c0]; "Group variables for counter q1,q0 pin istype ’reg, buffer’; "State variables sreg = [q1,q0]; "State Values A = 1; B = 2; C = 3; D = 0; Equations [q1,q0].clk = clk; count.clk = clk; State_Diagram sreg; State D: "Initial state; figure out where to go if (AD) then C; "Don’t count if input is initially high else A; State A: "Input is low, waiting for high count := count.fb; if (AD) then B; else A; State B: "Increment counter then move on! count := count + 1; if (1) then C; State C: "Input is high, waiting for low count := count.fb; if (!AD) then A; else C; END
Note that state variable values have changed! Result, no initial count, jumps to state C (3):
17
UniDirectional Pulse Count with a Strobe Counter cannot be read asynchronously Multi-bit changes Use a “stobe” signal -copies contents of counter to an output register Can cause some delay in recognizing a pulse transition if strobe is active Maximum pulse frequency for a given clock is thus lower
18
A’S’ A’
s0 power-up
s1
A’S’ # A’S
A’S A’S
AS’
AS
unc
s7 copy
AS’
unc
s8
AS
A: pulse input S: strobe input #: OR
ABEL code: MODULE StrbDcd TITLE ’Unidirectional Decoder with Strobe’ "Implements the ui\ni-directional decoder with the "addition of a strobe input that causes the count "register to be copied to an output register "This adds a potential extra delay, so decreases "the maximum pulse input frequency for a given clock "Inputs AA SS
s5 count
AS’ # A’S’
unc s6
s3 AS
AS’ # A’S’ AS s4 count
A
unc
s2 copy
pin; "Pulse input pin; "Strobe input
19
A’S
CLK
pin; "Clock input
"Outputs R2..R0 pin istype ’reg,buffer’; "Output register out_reg = [R2..R0]; "Group values Q3..Q0 pin istype ’reg, buffer’; "State variables sreg = [Q3,Q2,Q1,Q0]; "State register "Internal nodes c0,c1,c2 node istype ’reg, buffer’; "3-bit internal counter count = [c2..c0]; "Group variables for counter "State Values s0=0; s1=1; s2=2; s3=3; s4=4; s5=5; s6=6; s7=7; s8=8; Equations [Q3,Q2,Q1,Q0].clk = CLK; count.clk = CLK; out_reg.clk = CLK; State_Diagram sreg; State s0: "Initial state; figure out where to go if (AA) then s6; "Don’t count if input is initially high else s1; State s1: "Input is low, waiting for high or strobe count := count.fb; out_reg := out_reg.fb; if (!AA & !SS) then s1; else if (!AA & SS) then s2; else s4; "((!AA & !SS) # (!AA & SS)) State s2: "Copy count to register count := count.fb; out_reg := count; if (1) then s3; "Unconditional transition State s3: "Register has been copied count := count.fb; out_reg := out_reg.fb; if (!AA & SS) then s3; "Stay here else if (!AA & !SS) then s1; else if (AA & SS) then s5; else s4; " (AA & !SS) State s4: "Count count := count + 1; out_reg := out_reg.fb; if(1) then s6; State s5: "Count count := count + 1; out_reg := out_reg.fb; if(1) then s8; State s6: "Pulse is high count := count.fb; out_reg := out_reg.fb; if (AA & !SS) then s6; "Stay here else if (AA & SS) then s7; else s1; "((!AA & !SS) # (!AA & SS)) State s7: "Copy count to register
20
count := count.fb; out_reg := count; if (1) then s8; "Unconditional transition State s8: "Register has been copied count := count.fb; out_reg := out_reg.fb; if (AA & SS) then s8; "Stay here else if (!AA & SS) then s3; else s6; "(AA & !SS) # (!AA & !SS) END
Results:
Alternate Approach Uses modules to simplify design (Directory: A-Strobe2)
21
H # A’ A’
s0 power-up
S’
AH’
s1 A’H’
s2 count
s0 H=0
H count
A
S’
unc
s3
S
s5 H=0
H#A
unc A: S: H: #:
s4 copy
pulse input strobe input hold OR
(Note -- state s3 in lefthand diagram needn’t actually wait on H) Schematic:
ABEL code for decoder module: MODULE dcd TITLE ’Unidirectional Pulse Decoder’ "Implements the uni-directional decoder with the "addition of a strobe input that causes the count "register to be copied to an output register "This adds a potential extra delay, so decreases "the maximum pulse input frequency for a given clock "This version uses separate modules for decoding and copying "This is the decoding module
22
S
s1 H=1 unc s2 delay unc
s3 unc delay
"It works by preventing a count cycle while H is ON "Inputs A H CLK
pin; "Pulse input pin; "Hold signal -- prevents counting pin; "Clock input
"Outputs c2..c0 pin istype ’reg,buffer’; "Count output count = [c2..c0]; "Group variables for counter "Internal nodes Q1..Q0 node istype ’reg, buffer’; "State variables sreg = [Q1,Q0]; "State register "State Values s0=0; s1=1; s2=2; s3=3; Equations [Q1,Q0].clk = CLK; count.clk = CLK; State_Diagram sreg; State s0: "Initial state; figure out where to go if (A) then s3; "Don’t count if input is initially high else s1; State s1: "Input is low, waiting for high count := count.fb; if (A & !H) then s2; else s1; State s2: "Count count := count + 1; if (1) then s3; "Unconditional transition State s3: "Input is high, waiting for low count := count.fb; if (!A & !H) then s1; else s3; END
ABEL code for Copy module: MODULE copy TITLE ’Copy counter contents to output register’ "This model copies the counter inputs from the decoder to "the output register. To do that, it sends out a HOLD signal, "waits a few clock pulses to make sure the decoder is not counting, "then copies. "Inputs c2..c0 pin; "Counter count = [c2..c0]; "Group variables S pin; "Strobe input CLK pin; "Clock
23
"Outputs r2..r0 pin istype ’reg,buffer’; "Output register out_reg = [r2..r0]; H pin istype ’reg,buffer’; "HOLD output "Internal nodes Q2..Q0 node istype ’reg, buffer’; "State variables sreg = [Q2,Q1,Q0]; "State register "State Values s0=0; s1=1; s2=2; s3=3; s4=4; s5=5; Equations [r2..r0].clk = CLK; H.clk = CLK; [Q2,Q1,Q0].clk = CLK; State_Diagram sreg; State s0: "Waiting for strobe H := 0; out_reg := out_reg.fb; if (S) then s1; "Start copy procedure else s0; "Stay here State s1: "Set hold signal H := 1; out_reg := out_reg.fb; if (1) then s2; "Unconditional transition State s2: "Delay H := 1; out_reg := out_reg.fb; if (1) then s3; "Unconditional transition State s3: "Delay H := 1; out_reg := out_reg.fb; if (1) then s4; "Unconditional transition State s4: "Copy H := 1; out_reg := count; if (1) then s5; State s5: "Wait for stobe to clear out_reg := out_reg.fb; H := 0; " Clear hold if (!S) then s0; else s5; END
24
25