APPENDIX 1 (Courtesy of Xilinx Inc.)

advertisement
APPENDIX 1
(Courtesy of Xilinx Inc.)
APPENDIX 2
(Courtesy of Xilinx Inc.)
www.xilinx.com
APPENDIX 3
(Courtesy of Altera)
Stratix II Family of FPGA
www.altera.com
APPENDIX 4
(Courtesy of Actel)
Axcelerator Family of FPGAs Based on Antifuses
High Performance
With 7 layers of metal on a .15µm process, the Axcelerator family was designed
for speed and total logic utilization. Redesigned flexible logic modules,
highway tracks for carrying signals across the chip, extensive carry chain
support, and many other innovative attributes have been implemented in the AX
architecture to guarantee a high performance solution. Axcelerator FPGAs
achieve better than 500 MHz internal and 350 MHz system performance.
Low Power
Using high performance FPGAs often means high power. Not so with
Axcelerator FPGAs! Axcelerator features the lowest standby power of any
million-system gate FPGA, up to 1/5 of its nearest SRAM competitors. In
addition, Axcelerator has the lowest dynamic power of any competing SRAM
FPGA. Since Axcelerator FPGAs are nonvolatile, they are live at power up so
there's no in-rush current spike as with SRAM FPGAs, further simplifying
system power supply design.
Lowest Total System Cost
Because Axcelerator FPGAs are a single-chip, live-at-power-up solution, they
offer the lowest overall solution cost. No boot PROMs, no external CPLDs, and
no external power monitoring devices are needed. Moving functions into the
FPGA that are normally reserved for CPLDs reduces the overall user I/O
requirement of the FPGA and can allow for a smaller, cheaper FPGA to be
used. Since Axcelerator FPGAs are live at power-up, the on-chip PLLs can be
used for board-level clock distribution, eliminating more components from the
board.
The High-Security Solution
FPGAs are quickly becoming the new alternative to ASICs. Many systems
today have a significant portion of the total system-level IP inside the FPGA.
Since a conventional SRAM-based FPGA is volatile, it must be re-initialized
every time power is applied. This re-initialization requires an external bitstream
is loaded into the FPGA. This external bitstream also allows easy, noninvasive
copying of the design. Unlike SRAM-based FPGAs, Axcelerator does not
require an external bitstream and provides significantly higher design security.
The FuseLock™ secure programming technology used in the Axcelerator
family is highly resistant to both invasive and noninvasive security attacks.
Firm-Error Immunity
Firm errors occur when high-energy neutrons, generated in the upper
atmosphere, strike a configuration cell of an SRAM FPGA. The energy of the
collision can change the state of the configuration cell and thus change the logic
and/or routing in an unpredictable and uncontrollable way. These errors are
impossible to prevent in SRAM FPGAs and costly to detect. The consequences
of this type of error could result in a complete system failure. Firm errors are
nonexistent in Axcelerator FPGAs. The configuration element of Axcelerator
FPGAs, the antifuse, cannot be altered once programmed and is therefore
immune to both ground and aero particle effects.
Specifications
ƒ
ƒ
ƒ
ƒ
ƒ
Up to 2 Million Equivalent System Gates
Up to 684 I/Os
Up to 10,752 Dedicated Flip-Flops
Embedded SRAM/FIFO up to 295kbits
Manufactured on Advanced 0.15mm, 7 Layers of Metal, CMOS
Antifuse Process Technology
Features
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
Single-Chip, Nonvolatile Solution
Up to 100% Resource Utilization with 100% Pin Locking
1.5V Core Voltage for Low Power ·
Flexible, Multi-Standard I/Os
Embedded Memory Variable-Aspect RAM/FIFO Blocks
Segmentable Global Clock Resources
Embedded Phase-Lock Loop
Deterministic, User-Controllable Timing
Unique In-System Diagnostic and Debug Capability with Actel Silicon
Explorer
Boundary Scan Testing in Compliance with IEEE Standard 1149.1
(JTAG)
Secure Programming Technology Prevents Reverse Engineering and
Design Theft
350 MHz System/500 MHz Internal Performance
700mb/s LVDS Capable I/O
Axcelerator Family Selector Guide
AX1 25
AX2 5 0
AX 50 0
AX1 00 0
AX2 00 0
1 25, 000
2 5 0, 0 00
50 0,0 00
1, 000 ,0 0 0
2, 000 ,00 0
Typi ca l Ga tes
8 2,0 00
1 5 4, 0 00
28 6,0 00
6 12,0 00
1, 060 ,00 0
To ta l R AM Bi ts
1 8,4 32
5 5 ,2 96
73 ,7 2 8
1 65,8 88
2 94,9 12
Ma x R e gi s te rs
1 ,344
2 ,81 6
5 , 37 6
12 ,09 6
21 ,50 4
To ta l Modules
2 ,016
4 ,22 4
8 , 06 4
18 ,14 4
32 ,25 6
6 72
1 ,40 8
2 , 68 8
6 , 04 8
10 ,75 2
4
12
16
36
64
84
1 24
168
25 8
34 2
8
8
8
8
8
User I/Os
1 68
2 48
336
51 6
68 4
I/ O Re g is te rs
5 04
7 44
1 , 00 8
1 , 54 8
2, 05 2
CS180
FG2 56
FG3 24
CQ208
CQ352
F G2 5 6
F G4 8 4
PQ2 08
CQ208
CQ352
F G48 4
F G67 6
PQ20 8
BG72 9
CQ35 2
CG62 4
FG48 4
FG67 6
FG89 6
CQ35 2
CG62 4
FG89 6
FG1 15 2
Equ i v. S ys te m Gat es
Dedicate d Registers
R AM Bl oc ks
Ma x No . of LVDS Pa irs
PLL s
Pa ck ag es
www.actel.com
APPENDIX 5
Courtesy of
APPENDIX 6
(Courtesy of Monolithic Memories)
Medium 20 Series, 16R6 PAL Logic Diagram
1
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
16 17 18 19
20 21 22 23
24 25 26 27
28 29 30 31
0
1
2
3
4
5
6
7
19
2
8
9
10
11
12
13
14
15
+
A
A
18
B
17
C
16
D
15
E
14
D Q
Q
3
16
17
18
19
20
21
22
23
B
+
D
Q
Q
4
24
25
26
27
28
29
30
31
C
+
D Q
Q
5
+
32
33
34
35
36
37
38
39
D
D Q
Q
6
40
41
42
43
44
45
46
47
E
+
D Q
Q
7
8
9
+
48
49
50
51
52
53
54
55
F
D Q
F
13
Q
56
57
58
59
60
61
62
63
12
11
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
16 17 18 19
20 21 22 23 24 25 26 27 28 29 30 31
20
10
VCC
GND
APPENDIX 7
Verilog Design Quick Reference
Note:
Language constructs not supported by most Synthesis Tools are not included.
1. Module
module module_name (list of ports);
input / output / inout declarations
wire declarations (outputs of ‘assign’ statements)
reg declarations (outputs of ‘always’ block statements)
integer declarations
parameter declarations
gate instantiations
module instantiations
concurrent statements
endmodule
2. Concurrent Statements
// Combination circuits
Following statements are processed concurrently, i.e., simultaneously.
assign net_name = (arithmetic or logic expression);
// There can be any number of ‘assign’ statements, all of which process
concurrently.
always @ (inputs in sequential statements separated by ‘or’)
begin
{sequential statements}
end
// There can be any number of ‘always’ blocks, all of which process
concurrently.
// Sequential circuits
always @ (posedge clk or negedge reset_n)
begin
{sequential statements}
end
// There can be any number of ‘always’ blocks, all of which process
concurrently.
3. Signal Types
i. Nets:
wire, wand, tri, wor
These are continuously driven and get new values when driver changes.
Examples:
wire [7:O] data_out_1;
wire [15:O] data_out_2;
assign data_out_1 [7:O] = data_in [7:O]; // Unconditional statement.
assign data_out_2 [15:0] = enable ? data_in [15:0]: 16'bz;
// Conditional (MUX realization).
ii. Registers:
reg
These represent memories and store last assigned values.
They can be multi-bits.
Examples:
reg control_signal_1;
reg control_signal_2;
@ (posedge clock) control_signal_1 = 1'b1;
// Assigned at positive edge of clock.
@ (clear) control_signal_2 = 1'b0;
// Assigned at both edges of ‘clear’.
4. Sequential Statements
The constructs “if-else if-else” are processed sequentially and can be used
for assigning priority.
Example:
assign cnt_next = cnt_reg + 1; // Increment the counter in advance.
always @ (posedge clk or negedge reset_n)
begin // The following statements are processed sequentially.
if (reset_n == 1'b0)
cnt_reg <= 6'd0 ;
else if (hold == 1'b1)
cnt_reg <= cnt_reg ;
else if (encnt == 1'b1)
cnt_reg <= cnt_next ;
else
cnt_reg <= cnt_reg ;
// Top most priority.
// Lowest priority.
end
Without ‘else’ statement, undesirable latch is created.
5. Case Statements
Case statements serve as switches and offer faster implementations than
“if-else if-else” constructs. Without default statement, latch is created. Case
statements can be nested.
i. Case
case (signal or expression)
2'd0 :
OUT = A + B;
// There can be any no. of conditions instead of 4.
2'd1 :
OUT = A – B;
2'd2 :
OUT = C + D;
default: OUT =0;
endcase
ii. Casex
casex (control)
4'bxxx1 :
4'bxx1x :
4'bx1xx :
4'b1xxx :
default:
state = 0;
state = 1;
state = 2;
state = 3;
state = 0;
// ‘x’ is a don’t care.
endcase
6. Gate Primitives
and
or
(out, in1, in2);
(out, in1, in2);
nand
nor
(out, in1, in2);
(out, in1, in2);
xor
buf
bufif0
notif0
(out, in1, in2);
(out, in);
(out, in, select);
(out, in, select);
xnor
not
bufif1
notif1
(out, in1, in2);
(out, in);
(out, in, select);
(out, in, select);
7. Operators
+-*/
%
arithmetic: add, subtract, multiply, divide
modulus
{}, {{}}
concatenation, replication
!
&&
||
logical negation
logical and
logical or
>
<
>=
<=
greater than
less than
greater than or equal to
less than or equal to
==
!=
logical equality
logical inequality
~
&
|
^
^~ or ~^
&
~&
|
~|
^
~^ or ^~
<<
>>
?:
or
bit-wise negation
bit-wise and
bit-wise or
bit-wise exclusive or
bit-wise equivalence
reduction and
reduction nand
reduction or
reduction nor
reduction xor
reduction xnor
left shift
right shift
conditional
Event or
Example of concatenation/replication:
If A=2’b11, B=4’b1010, then { 2{A}, B } = 11111010.
Reduction operators use only one operand. They work bit by bit from left to
right on one vector operand. For example, if A=4’b1101, then ^A is
1^1^0^1=1’b1.
8. Parameter
// Constants may be defined using the keyword ‘parameter’.
parameter width = 16;
// Define signal widths and
input [(width-1):0] din;
reg
[(width-1):0] qr0;
// use them where required
// in the code.
// If the parameter is to be changed, one needs to change only the width
// value instead of changing values at all the places of their occurrence.
9. Memory Instantiation
reg
[15:0]
memory [4095:0]; // Declare memory.
assign data_out = memory [4000];
// Read from a specific memory location.
10.
Blocking and Non blocking Statements
always @(posedge clock)
begin
A = B;
B = A;
// These blocking (=) statements
// exhibit race condition.
// Not permitted by most Synthesis tools.
end
always @(posedge clock)
begin
A <= B; // These non blocking (<=) statements
B <= A; // do not exhibit race condition.
// Perform true swapping operation.
end
11. Compiler Directive
`include “sub_design_file.v”
// Design is a file called “sub_design_file.v”.
// Any number of files can be included.
Verilog is a registered trademark of Cadence Design Systems, lnc.
APPENDIX 8
Verilog Test Bench Quick Reference
1. Module
module module_name (list of output ports, if required);
reg declarations (outputs of ‘always’ block statements, if any)
wire declarations
(outputs of ‘assign’ statements, if any, and test bench outputs)
integer declarations
parameter declarations
design module instantiations
concurrent (assign/always block) statements, if any
endmodule
2. Concurrent Statements
‘initial’ blocks are processed simultaneously. There can be one or more
numbers of ‘initial’ blocks.
initial
begin
{sequential statements_1}
end
initial
begin
{sequential statements_2}
end
3. Sequential Statements
i. initial
begin
// 50 MHz clock.
clock = 0;
forever #10 clock = !clock;
end
ii. always
// Toggle every 10 ns.
#10 clock = !clock;
// Toggle every half clock cycle.
iii. initial
begin
i=0;
while ( i < 100)
begin
// Process for i = 0 to 99.
$display(“Iteration Number = %d”, i);
i = i+1;
end
end
iv. for (i = 0; i < 100; i = i+1 )
// Process for i = 0 to 99 in steps of 1.
begin
$display(“Iteration Number = %d”, i);
end
v. Repeat construct processes a loop a fixed number of times.
initial
begin
i=0;
repeat (100)
begin
// Process for i = 0 to 99 in steps of 1.
$display(“Iteration Number = %d”, i);
i = i+1;
end
end
vi. wait (ready) ;
// Wait for ready to go high.
vii. Block Types
Sequential block
initial
begin
// Simulation time is cumulative.
#10
#15
end
A = 4’d7;
B = 4’d9;
Y = A+B;
// Completes at time 0 ns
// Completes at time 10 ns
// Completes at time 25 ns
Parallel block
initial
fork
// Simulation time is concurrent.
#10
#15
A = 4’d7;
B = 4’d9;
Y = A+B;
// Completes at time 0 ns
// Completes at time 10 ns
// Completes at time 15 ns
join
4. Memory Instantiation
initial
begin
$readmemh ("image.txt”, memory);
// Read the disk file "image.txt” in hex format and store the
// contents in ‘memory’.
// $readmemb can be used for binary values.
fp1 = $fopen ("dctq.txt");
// “dctq.txt” is the DCTQ output of the image
// frame, “image.txt”.
for (j=0; j<100; j=j+1)
$display ("Memory [%d] = %h", j, memory[j]);
// Display contents of memory.
#700000
// Run long enough to process the entire frame.
$fclose(fp1);
$stop;
end
// Close the output file and
// stop the simulation.
5. Compiler Directives
`define clkperiodby2 5
`include “design_file.v”
// clkperiodby2 = 5 units of time, say, 5ns.
// Design is a file called “design_file.v”.
`timescale l0ns/1 ns
// Time unit and its precision.
6. Display of Outputs
$display (" External RAM test: PASS ") ;
// Display the message on the monitor.
$display (" External RAM test: FAIL => Last address @ %d\n", addr) ;
// %h for hex, %o for octal, %s for string, %c for character,
// %e for scientific format, %f for decimal format.
// For new line: ‘\n’.
$monitor($time," ns switch = %b
$monitoron;
$monitoroff;
out = %b", switch, out);
// Monitor the I/Os.
// Switch on or off monitoring.
// $time may also be used in $display.
// Unlike $display, $monitor may be invoked only once in the code.
7. Simulation Control
initial
begin
$dumpfile ("sim_results.dump");
// Simulation results written into the file.
$dumpvars;
// Dump all signals in the design.
$dumpvars (1, top);
// Dump variables in module instance ‘top’.
$dumpvars (2, top.ml); // Dump up to 2 levels below ‘top.m1’.
$dumpvars (0, top.ml);
// Dump the entire hierarchy below ‘top.m1’.
end
#1000 dumpon;
#10000 dumpoff ;
// Start (or restart) dump after 1000 ns.
// Stop dump after 10000 ns.
$stop;
// Stop simulation.
$finish;
// Quit simulation.
APPENDIX 9
HDL Coding Guidelines
This describes the HDL coding guidelines that are recommended for
engineers based on practices in industries. The idea of these guidelines is to
make the HDL code compatible with tools and scripts that are used during
development without curtailing the creativity of engineers. All the RTL source
files should comply with these guidelines. The RTL code shall be reviewed
against these guidelines.
1. Editor Guidelines
1. Use standard editors such as Wordpad, Vi, Vim, ModelSim.
2. A line should not contain more than 80 characters.
3. Avoid using tabs if possible since indentation is altered with the change
of editor.
4. Use 3 to 5 spaces for indentation in a line and maintain it consistently.
5. Skip a line, if necessary, to enhance the readability.
6. Give meaningful signal/variable/file names and comments, preferably in
lower case.
2. Source and Revision Control
1. At the top of all source files, use a source control header such as Verilog
Source or VHDL Source as the case may be followed by include files,
synthesis scripts, make files, run scripts.
2. Maintain revision control in all the source files.
3. Add comments at every edit session mentioning the reason for the
change(s).
3. Hierarchy Guidelines
1. Each FPGA/ASIC design should have a top level module, a pad module
and a core module as applicable.
2. Maintain signal names across hierarchy, i.e., do not change names at
different hierarchies for the same signal as far as possible.
3. Do not use time scale directives in each module. Use it only in the test
bench and not in the design.
4. Top level module shall not have any logic in it. It shall be a structural
code instantiating various modules of the design. Push logic if any into
one of the lower hierarchy files.
4. Module and File Guidelines
1. Have only one module per file.
2. File name should be the same as the module name with ‘.v’ or ‘.vhd’
extension as the case may be.
5. Module Organization
1. A module comprises various parts in the following order.
•
•
•
•
•
•
•
•
•
•
•
•
•
Module header consisting of Copyright and CVS information,
Project name, File name, Version, Revision, Author, Date(s) of
creation and revision, References, Description, History of design
change or modification, etc.
Declaration of a module
Inclusion of child modules
Declaration of define variables and parameters
Declaration of reset(s) and clock(s)
Declaration of input ports
Declaration of output ports
Declaration of inout ports
Calling ports by name
Declaration of various signals such as ‘wire’ and ‘reg’.
Continuous assignment statements
Procedural statements
Declaration of end module
Module Header Template
/*
--------------------------------------------------------------------------------------Source File
: Verilog
Project
: H.264 Video Encoder
File Name
: encoder.v
Version
: 1.0
Revision
: 1.0
Author
: <Author>
Creation Date
: <Date>
References
: H.264_Video_Encoder_Design_Specs._1.0
Description
: Video Encoder to process high resolution color
motion picture at 30 frames/second.
--------------------------------------------------------------------------------------Modification History :
<Details with dates>
--------------------------------------------------------------------------------------*/
2. Declare the inputs and outputs in the same order as they occur in the
module declaration.
3. Port names shall be one name per line both in the module declaration and
the port declarations.
4. Signals shall be grouped and placed in the order of their occurrences in
the design module.
5. Provide a blank line in between a single bit width signal group and a
multi-bit width signal group declarations.
6. Segregate ‘wire’ and ‘reg’ groups by providing one blank line in between
them.
7. ‘Always’ and ‘initial’ blocks shall start from extreme left without any
spaces or tabs.
8. “begin” can be in the same line with ‘always’ or ‘initial’ key word or on
the next line after a blank line with first letter aligned with first letter of
always or initial block or after a tab. “end” shall be aligned with the
corresponding “begin”.
9. Use empty lines to separate different parts of the module.
10.Comment all the inputs, outputs and the logic. Update comments
whenever the code is changed.
11. The purpose of the above guidelines is to enhance the readability of the
design and also to establish a standard practice.
6. Signal Naming Conventions
1. Signal names shall contain only lower case alpha-numeric letters and
underscores with an alpha letter as the first character.
2. Use meaningful names for signals.
3. Signal names shall not be case sensitive. For example, do not use ‘data’
and ‘DATA’ to designate two different signals.
4. Separate signal names and numbers by using underscores. Ex.: cnt_reg_1
or cnt1_reg instead of cntreg1 to improve readability.
5. For active-low signals, add suffix “_n”. Ex.: reset_n.
6. Use standard names such as data, addr, data_valid, enable, set, reset,
ready, hold, clk, etc. for commonly occurring signals.
7. Order the bits from large to small value. Ex.: data [15:0] is preferred
instead of data [0:15].
8. Do not use FPGA specific names like IOB, CLB, OSC, CCLK, BUFGS,
BUFTS, DP, GND, VCC, RST; TDO, BSCAN, Pin/pad names such P1
and PAD1, etc.
7. Module Instantiation
1. As far as possible, instantiation of modules shall be given the same name
as the module name with suffix: _1 and so on, depending on the number
of instantiations. Ex.: ram
ram_1 (I/0 list)
2. Give at least four spaces (or a tab if preferred) between the module name
and the instantiating name.
3. While instantiating a module, all signals in that module shall also be
instantiated, whether used or not. This helps in avoiding warning
messages while running the tools.
4. Signal names shall be one per line, calling ports by name.
Ex.: .addr(addr)
5. Do not concatenate signals while calling ports by name.
Ex.:
process process_1 (
.control ({cntrl_1, cntrl_3, cntrl_5}),
.
.
);
Instead, do:
assign cntrl = {cntrl_1, cntrl_3, cntrl_5};
process process_1 (
.control (cntrl),
.
.
);
8. Procedural Statements
1. Use character/line spaces to make the code more readable.
2. Use parenthesis in assignment and decision statements to give more
logical feel.
3. Break long decision and assignment statements at a logical place.
4. Break long lines of code at appropriate point such as at a symbol or at
parenthesis to make codes more readable.
Example:
assign adv_cnt1 = ( (set_time != 1)&(tbsec == 1)&(cnt1_reg < 2)&
(cnt2_reg == 9)&(cnt3_reg == 5)&(cnt4_reg == 9)&
(cnt5_reg == 5)&(cnt6_reg == 9) )|
( (adv_hrs_time== 1)&(cnt1_reg < 2)&(cnt2_reg == 9) ) ;
5. Use blocking construct “=” for the ‘assign’ statement and non-blocking
construct “<=” for the values assigned to registers in ‘always’ blocks.
6. Describe briefly the function of a module inside the module.
7. “if – else if - else” statements and “case” statements must have default
values within the block of statements.
8. “case” statements can be nested. “endcase” shall have comment
identifying the case statement that is complete.
9. Use “case” in preference to “if” unless priority encoding is required.
10. Avoid using (!reset) or (~reset) in “if” statements. Instead, use (reset_n
== 1b’0) to improve the readability.
11. Avoid “begin” and “end” for single line statements in an ‘always’ block.
It helps in reducing the simulation time.
12. Separate the combinational and sequential logic to improve the
processing time.
Example:
Don’t:
always @ (posedge clk or negedge reset_n)
begin
if (reset_n == 1'b0)
ready <=
1'b1;
else if ( (start_reg1 == 1'b1)&&(cnt1_reg ==6'd01) )
ready <=
1'b1;
else
ready <=
!start_reg1 ;
end
Do:
assign swon_ready = ( (start_reg1 == 1'b1)&&(cnt1_reg ==6'd01) );
always @ (posedge clk or negedge reset_n)
begin
if (reset_n == 1'b0)
ready <=
1'b1;
else if (swon_ready == 1)
ready <=
1'b1;
else
ready <=
!start_reg1 ;
end
13. Do not have more than 3 or 4 “if – else if - else” statements. Processing
speed goes down beyond that since MUXes are cascaded.
14. Include liberal and meaningful comments to make code readable, which
in turn reduces debugging time, is easier to maintain and disseminates
knowledge to other users. Commence and sustain the comment writing
right from inception of the project and not towards the completion of the
project.
15. Combinational feedback is strictly forbidden.
16. Follow the RTL coding guidelines scrupulously, without which, no
design can work on the chip.
17. A signal should be driven from only a single process or ‘always’ block
statements and not multiple blocks.
18. Do not assign initial values to signals and variables since synthesis tools
ignore the initial values. Instead, use assign statement to initialize.
Don’t:
Verilog:
wire data_in=16b’0;
VHDL:
variable data : INTEGER : = 0;
9. Parameters and Define statement
1.
2.
3.
4.
Use capital letters for parameters and defines.
Avoid using long path identifiers.
Separate the words with under score.
All parameters shall be declared as contiguous statements at the
beginning of the module and not distributed throughout the code.
5. Use constants as much as possible and declare them as parameters or
defines. Avoid using magic numbers in the code.
Example of parameter:
parameter
WIDTH = 11 ;
output
[(WIDTH-1):0]
qr0;
Example of define:
`define clkperiodby2 5
// Both clocks clk & pci_clk operate
// at 100 MHz.
`define pci_clkperiodby2 5
`define NUM_BLKS 1024 // Defines no. of blocks in a frame. A picture
// of resolution 256x256 pixels contains
// 1024 blocks.
always
#`clkperiodby2 clk
<= ~clk ;
always
#`pci_clkperiodby2 pci_clk <= ~pci_clk ;
// Run the clocks.
10. Finite State Machine (FSM)
1. Keep the system controller (FSM) in a separate file and do not mix any
data within the controller module.
2. As far as possible, meaningful state names shall be used in parameter or
define declarations, instead of s0, s1, etc.
3. Every state shall have a brief description at the beginning to indicate the
purpose of that state.
4. Use ‘case’ for realizing an FSM.
5. Generate only one output in an ‘always’ block. Occasionally, one can use
multiple outputs in an ‘always’ block.
6. Separate the combinational and the sequential logic.
11. Clocks, Resets and Presets
1. Use only positive edge clocks. Only in exceptional cases, negative edge
clocks may be used.
2. Do not use a clock in the data path of a flip-flop.
3. Do not gate clocks. Drive clocks directly from input pins.
4. Internally generated clocks must be controllable using proper inputs.
5. All frequency dividers must be resettable.
6. Do not generate asynchronous set or reset for a register internally. If
these signals are required for an application, they must come from inputs.
Don’t:
assign cnt1_next = cnt1_reg + 1 ;
// Pre-increment the counter.
always @ (posedge clk or negedge reset_n or posedge res_cnt1)
begin
if (reset_n == 1'b0)
cnt1_reg <= 4'd0 ;
else if (res_cnt1 == 1'b1)
cnt1_reg <= 4'd0 ;
else if (adv_cnt1 == 1'b1)
cnt1_reg <= cnt1_next ;
// Initialize when the system is reset.
// Reset if external reset is applied.
// Advance the count once if the
// time watch is still running.
else
cnt1_reg <= cnt1_reg ;
end
Do:
// Otherwise, don't disturb.
assign cnt1_next
assign reset_cnt1
= cnt1_reg + 1 ;
// Pre-increment the counter.
= (reset_n==0) || res_cnt1 ;
// Combine reset logic.
always @ (posedge clk or negedge reset_n)
begin
if (reset_cnt1== 1'b1)
cnt1_reg <= 4'd0 ;
else if (adv_cnt1 == 1'b1)
cnt1_reg <= cnt1_next ;
// Initialize when the system is reset.
// Advance the count once if the
// time watch is still running.
else
cnt1_reg <= cnt1_reg ;
// Otherwise, don't disturb.
end
12. Latches and Tri-states
1. As far as possible, avoid using latches since they pass on the glitches and
consequent malfunctioning of system. Use latches only when absolutely
necessary.
2. Avoid tri-state busses in internal circuitry, if MUX based solution is
possible.
3. Use bus hold signals for all internal tri-state busses.
4. Decode tri-state enables fully in order to allow only one driver at a time.
Download