Chuck Benz ASIC and FPGA Design
I have been designing ASICs and FPGAs for over 20 years now, and want to
share some of what I've learned, as well as some open source tools
that are also the result of my experiences.
I am sometimes available for part-time or full-time consulting in the
Boston/Nashua area, short-term or long-term, for design or RTL code
reviews, architecture discussions/reviews, design implementation, or
generate verilog RTL code for processor memory maps in ASIC/FPGA designs
csrGen perl script
csrGen is a tool to automatically build verilog RTL for the CSRs in
processor interfaces of many ASIC/FPGA designs. csrGen was described in EE
Times on Sept 9, 2002, and presented in my paper at SNUG San Jose, 2003
(SyNopsys Users Group). An updated
user's manual is now available, with additions and corrections to
the info in the SNUG paper. An older, briefer description of csrGen
is csrGen.txt. example.csrs
is a very simple example of how to use csrGen and example_lp.v
is the resulting verilog code. Also, I recently wrote
some notes on how to adapt 2 interfaces (separate asynchronous
to one set of CSRs.
Updated: Aug '04 csrGen now produces HTML documentation of the
map. Any info contained between double quotes will be put into the
description column for the address or register field. The HTML can then
be copied into
other document editors, for example it works great with MS Word.
cbaf_cgss.v is a simple SPI slave. I prepared this
so I can prepare an example for csrGen for SPI.
cbaf_cgss_tb.v is a simple testbench.
And here's an example of using this SPI slave logic with csrGen:
Comments on Fifos,
Talking (too much) about fifos and
code on blocks of data
This Hamming Code writeup explains how
to apply Hamming code to a block of data. With n bits, Hamming code can
protect a block of (2^n - n - 1) bits against single bit errors
(allowing detection and correction). The writeup explains how to
calculate and apply correction, how to arrange data for easiest design,
and how 1 more protection bit extends coverage to double bit detection.
Logic Investigator: "li" - a tool for
analyzing logic, particularly clock domain crossings.
I wrote li to examine designs in Altera's EQN format to check signals
that crossed clock domains. It could be enhanced to read other formats
as well. Once the design has been read into data structures, they can
be traversed to check different properties. It should be easy to add
other types of checks.
li.tar - Logic Investigator perl script and readme
My open source
I was not comfortable using the opencores.org 8b10b encoder/decoder
because it's licensing terms were unclear to me - particularly whether
LGPL when applied to hardware might still be in some way viral, and
because when reusing verilog code, it's inevitable that you need to
change it slightly - at least the module name is commonly changed, and
the terms seemed to prevent even that. I'm willing to share this
implementation very freely. Here you will find an 8b10b
encoder, a 8b10b decoder, and a testbed to prove them, all in verilog.
Also, a table used by the testbench for the
codes - this is raw 1's and 0's taken from a standard. So, the
encoder/decoder files are:
8b/10b is of course now used for Fiberchannel, Gigabit Ethernet,
10Gigabit Ethernet, Infiniband, and PCI-Express.
machines - best practices for RTL coding in verilog
One hot state machines have advantages, but it's tricky to write RTL
code that produces the minimal logic that you intend. Here are my recommendations for
one hot state machines.
Mistakes to learn from
Over the years, I've made and seen many mistakes that offer good lessons.
This is a RS232 interface that can be added to an FPGA design to add
debug access to internal registers and memories. It implements a simple
protocol over RS232 that can be used from a terminal to read and write
memory map contents or added registers. The protocol also adapts readily
to being used from a program.
The protocol uses "packets" in the form of:
X is the character 'X' or 'x',
c is a character specifying the command (A, B, G, and H are defined)
rr is two characters as hex digits representing an optional crc8
aaaaaaaa is 8 characters as hex digits representing a 32 bit address
dddddddddddddddd is 16 chars as hex digits representing 64 data bits
The hex digits should be 0-9 and a-f or A-F.
At any position, a space or _ can be inserted to aid readability
The point of this format is that it's usable from a terminal, but also
usable from a program sending packets to the logic.
In the basic design available here, the commands are:
A - write debug csr
B - write memory external to debug logic (memory map defined by user)
G - read debug csr
H - read memory external to debug logic
The debug csr is:
[63:48] - readonly value 0xCBAF - identifies this logic, can be changed
[47:32] - 16 bit scratch value - for testing writes/reads
[31:16] - count of csr and memory writes, write non-zero to clear
 - echo flag - 1 after reset, clear to disable echo to terminal
 - crcsupported - readonly - 1 if logic supports crc8 checking;
current logic does not, so value is 0.
 - checkcrc - if 1, only accept writes if crc in packet is correct.
Can only be set to 1 if crc is supported.
Files for the design are cbaf_serdebug.v,
(The UART files are from opencores.org).
more to come, someday: clock domain crossing, especially between
also more mistakes to learn from.
Chuck Benz asic-fpga (at)
Updated, 11-oct-2002 - 8b10b decoder and validation suite updated
13-sep-2002 - csrGen.pl features enhanced
25-mar-2003 - release csrGen SNUG paper.
10-jun-2003 - add Logic Investigator
17-jun-2003 - add one-hot writeup, mistakes.
3-aug-2004 - html docs out of csrGen.
aug-2005 - added sitlink info
24-oct-2006 - serial debug logic
18-apr-2010 - SPI slave logic with csrGen