The Open 7400 Logic Competition is a crowd-sourced contest with a simple but broad criteria for entry: build something interesting out of discrete logic chips. It’s now in its second year, and this time around I was inspired to enter it. Discrete logic, for anyone who isn’t familiar, are any of a number of families of ICs who each perform a single, usually fairly straightforward, function. Typical discrete logic ICs include basic logic gates like AND, OR and NAND, Flip-Flops, shift carry Ripple Adder – VHDL, and multiplexers.
For smaller components like gates and flipflops, a single IC will usually contain several independent ones. So, I wondered, wouldn’t building an FPGA out of discrete logic be similarly educational? Designing an FPGA from 7400s The most basic building block of an FPGA is the Cell, or Slice. The core of a slice, the Lookup Table, seems nearly magic – taking an array of inputs, it can be programmed to evaluate any boolean function on them and output the result. As the name implies, though, the implementation is very simple, and it’s a technique also used to implement microcode and other configurable glue logic. In principle, what you do is this: take a memory IC such as some SRAM or an EEPROM.
Bernat Softee Baby Yarn
Wire up the address lines to your inputs, and the data lines to your output. Unfortunately, none of the 7400 series memories are manufactured anymore, and while there are plenty of SRAMs and EEPROMs available, the smallest sizes available are significantly larger than what we want for a simple discrete FPGA. However, a simple solution presents itself: shift registers! A shift register is effectively an 8-bit memory, with serial inputs – convenient for our purposes – and each bit exposed on its own pin.
What is Bitcoin? | Help
By combining this with an 8-way multiplexer, we have a basic 3-input 1-output LUT. Our LUT can be reprogrammed using the data, clock, and latch lines, and many of them can be chained together and programmed in series. For our FPGA slice, we’ll use two of these discrete LUTs, with their inputs ganged together. Because a combined capability of 3 inputs and 2 outputs about the smallest you can implement interesting things with.
1-bit numbers together with carry requires multiple slices, which severely limits our capabilities. The next component is the flipflops, and the logic for selecting asynchronous or synchronous mode. There’s a profusion of flipflops and registers available, from 2 up to 8 in a single IC, and with various control methods, so that’s no problem. Choosing between synchronous and asynchronous is a little tougher. Fortunately, a 2-way multiplexer isn’t difficult to construct. There are several options, but the most efficient is to use tristate buffers. 126 that meet our requirements ideally.
Each contains four tri-state buffers, the only difference between the two chips being that one enables its output when the enable line is high, while the other enables its output when it is low. Now we’ve got the core of a basic slice designed, let’s look at the second major component of any FPGA: routing. Routing, though, uses a huge amount of resources to implement properly. What’s the minimum we can provide and still get a useful and interesting result? Typically, FPGAs position individual slices in a rectangular grid. Buses run between slices in the grid both horizontally and vertically. A slice is able to tap into some subset of the lines at its intersection, and can likewise output to some subset of the lines.
Typically, the bus can continue through a slice uninterrupted, or the bus can be ‘broken’, effectively creating separate buses on either side of the slice. 2 bit buses, both vertical and horizontal. Speaking of bus switches, we’ll go for the simplest configuration: a switch connecting each of the top and bottom lines, and a switch connecting each of the left and right lines, which can be opened or closed individually. 4066 “quad bilateral switch” IC provides a convenient way to do this in a single IC. With routing done, we’ve more or less designed the entire of a basic FPGA slice in discrete logic. 2 x 74HC125 and 2 x 74HC126 Tristate buffers, for multiplexers and output enables.
1 x 74HC173 4-bit register, for synchronous operation. 1 x 74HC4066 Quad Bilateral Switch, for bus switches. That’s a total of 12 discrete logic ICs to implement one moderately capable FPGA slice. Add a few LEDs to give a visual indicator of the status of the bus lines, and some edge connectors to hook them up together, and we have a board that can be ganged together in a rectangular configuration to make a modular, expandable discrete logic FPGA. Pointless, given that it’s a fraction of the capability of a moderately priced FPGA or CPLD chip?
Michael H. Jensen
Programming Of course, it’s no good having a DFPGA if there’s no way to program it. Porting VHDL or Verilog to something like this would be tough, and massive overkill given the number of slices we’re dealing with. Instead, I opted to implement a simple hardware description language, which I’ll call DHDL. A DHDL file consists of a set of slice definitions, followed by a list of slices to ‘invoke’, arranged in the same manner as the DFPGA is laid out. Here, l0, r1, etc, refer to bus lines – ‘u’, ‘d’, ‘l’ and ‘r’ for up, down, left, and right.
0 and r1, which the adder takes advantage of, since we can only select from one left bus line at a time. Carry input enters via the bus line u0. The first expression computes the sum of the two inputs and the carry, outputting it on r0. In some cases, we might want to configure the buses ourselves.
This slice uses feedback to store a value, by outputting it on r0 and reading it back from l0. Since outputting to r0 would normally cause the compiler to open the switch between l0 and r0, we explicitly tell it that we want the switch closed, making the feedback possible. This definition also demonstrates how we specify synchronous vs asynchronous behaviour, with the `sync` or `async` keyword before the assignment operator. Let’s see what a complete FPGA definition looks like. First we define some slices – the storage slice we already saw, and a comparer, which outputs a 1 to d0 iff both the horizontal bus lines are equal and its u0 input was 1. Operation is like this: To set the code, input the values on the l1 input of each of the leftmost slices, then take the top slice’s u0 input high for one clock cycle.
To test a combination, input the values on the l1 inputs again, but leave the top slice’s u0 input low. The bottom right slice’s d0 line indicates if the combination is correct. Finally, let’s try something a little bit more involved: a PWM controller. The first two slice definitions, toggler and counter, collectively implement a binary counter. Toggler is the least significant bit, while any number of counter stages can be chained vertically to make an n bit ripple-carry counter – in this case, we’ve constructed a 3 bit counter. By setting the 3 input bits to reflect the duty cycle required, and pulsing the clock line sufficiently fast, the srlatch slice’s r0 output will be PWMed with the appropriate duty cycle – which can be visually observed as the LED on that bus line being dimmed.
Comment by Fistycuffs
Fabrication Designing and building this board was an interesting exercise. Due to the number of ICs and wanting to make the PCB as compact as possible, this was by far the toughest board to route that I’ve designed so far. Since I had time constraints to get the board sent off for fabrication in time for the contest, I ended up using an autorouter for the first time. For fabrication, I went with the excellent Hackvana, who made me up 20 of the boards and had them to me in record time. Element14 saw me sorted for parts, and all that was left was hours and hours of soldering – with over 200 SMT pads on each board, the assembly process takes a while. Of course, as with any first iteration design, there were problems. A couple of minor design improvements occurred to me almost immediately, which would’ve increased the board’s capabilities somewhat, and the jumpers that let you determine how the serial programming stream connects between boards could be better placed.
More problematic, I accidentally tied all the shift registers’ reset lines low, when they’re actually active low – they should be connected to the 5v rail. Demonstration How does it look once assembled and working? It may not be anywhere near as capable as a real FPGA, but it’s also a lot easier to inspect and understand. With LEDs on all the bus lines you can see exactly what the internal state is at any time, which makes debugging a whole lot easier. Source All the design files, along with the DHDL compiler, test suite, and demo definitions are open source under the Apache 2.
You can find them all on Github here. If you decide to build your own DFPGA, or find the schematics or code useful in your own project – let me know! Future developments Remember how I rubbished the use of dedicated memory chips at the beginning, saying that all the ones available now are too big, and too difficult to interface with? Well that’s not quite as accurate as I thought when I was designing things. It’s true that the memory you can get is mostly larger than we need, but that can be an advantage in moderation – it means it’s possible to construct much more capable slices. How would you like a slice with 8 inputs and 4 outputs, that can output to any of the bus lines, and has 4 bits of internal state, allowing it to implement a 16 state state machine in each slice? And all with a little over half as many ICs as the design above?
The catch is this: the smallest SRAMs available are 256 kilobit, which is really quite large – so much so that an embedded processor like an Arduino could never program even one of these slices without external memory. We can use EEPROMS instead, which tend to be a bit smaller and could be easily programmed ahead of time, but that still leaves us needing a way to store the other configuration bits, such as the output enables. EEPROM shift registers, unfortunately, don’t really seem to exist. With a little clever optimisation, though, a compact design that loads the output enable state from the EEPROM at power on is possible, albeit somewhat more complicated than the current design. Unfortunately, I suspect the demand for discrete logic FPGAs – even fairly capable ones – is low, so it’s unlikely this design will ever see the light of day. Do you want your own discrete FPGA? Can you think of a practical use for one?
Let me know in the comments! As vlsi is a large ocean, large of concepts, less information available,more confusable. Synthesis is a complex task consisting of many phases and requires various inputs in order to produce a functionally correct netlist. The following chapter presents the basic synthesis flow with Synopsys Design Compiler. It assumes that you have a synthesizable and functionally correct HDL description available. Synthesis with Design Compiler include the following main tasks: reading in the design, setting constraints, optimizing the design, analyzing the results and saving the design database.
The first task in synthesis is to read the design into Design Compiler memory. Reading in an HDL design description consist of two tasks: analyzing and elaborating the description. Note: check the elaboration reports carefully to see the number and the type of memory elements Design Compiler thinks it should infer and whether you agree with it or not. Badly modeled hardware description may result as excessive or wrong type of memory elements inferred. At this point, if the elaboration completed successfully, the design is represented in GTECH format, which is an internal, equation-based, technology-independent design format.
Mauch,“A fixed frequency, fixed duty cycle Boost converter with ripple free input inductor current for unity power factor operation,’
The next task is to set the design constraints. Constraints are the instructions that the designer gives to Design Compiler. They define what the synthesis tool can or cannot do with the design or how the tool behaves. Design rules constraints are implicit constraints which means that they are defined by the ASIC vendor in technology library.
By specifying the technology library that Design Compiler should use, you also specify all design rules in that library. You cannot discard or override these rules. Design Compiler how to perform synthesis. The total capacitance comprises of load pin capacitance and interconnect capacitances. Some technology libraries contain cell degradation tables.
The cell degradation tables list the maximum capacitance that can be driven by a cell as a function of the transition times at the inputs of the cell. The optimization constraints comprise timing and maximum area constraints. Clock constraints are the most important constraints in your ASIC design. The clock signal is the synchronization signal that controls the operation of the system. The clock signal also defines the timing requirements for all paths in the design.
Most of the other timing constraints are related to the clock signal. A multicycle path is an exception to the default single cycle timing requirement of paths. That is, on a multicycle path the signal requires more than a single clock cycle to propagate from the path startpoint to the path endpoint. Input and output delays constrain external path delays at the boundaries of a design.
Input delay is used to model the path delay from external inputs to the first registers in the design. Output delay constrain the path from the last register to the outputs of the design. Minimum and maximum path delays allow constraining paths individually and setting specific timing constraints on those paths. These constraints can be used to constrain the input slew rate and output capacitance on input and output pins. A false path is a path that cannot propagate a signal. For example, a path that is not activated by any combination of inputs is a false path. Note that Design Compiler tries to meet both design rule and optimization constraints but design rule constraints always have precedence over the optimization constraints.
This means that Design Compiler can violate optimization constraints if necessary to avoid violating design rule constraints. Examples that follow show how to set these constraints. You also need to describe the environment in which the design is supposed to operate. These variations are taken into consideration with operating condition specifications in the technology library.
The cell and wire delays are scaled according to these conditions. Wire load models are used to estimate the effect of interconnect nets on capacitance, resistance, and area before real data is obtained from the actual layout. These models are statistical models and they estimate the wire length as a function of net’s fanout. The following section presents the behavior of Design Compiler optimization step. The optimization step translates the HDL description into gate-level netlist using the cells available in the technology library. The optimization is done in several phases. In each optimization phase different optimization techniques are applied according to the design constraints.
The following is somewhat simplified description of optimizations performed during synthesis. Design Compiler performs optimizations on three levels: architectural, logic-level, and gate-level. Architectural optimizations are high-level optimizations which are performed on the HDL description level. Arithmetic optimization uses the rules of algebra to improve the implementation of the design. That is, Design Compiler may rearrange the operations in arithmetic expressions according to the constraints to minimize the area or timing.
Resource sharing tries to reduce the amount of hardware by sharing hardware resources with multiple operators in your HDL description. For example, single adder component may be shared with multiple addition operators in the HDL code. Without resource sharing each operator in your code will result as a separate HW component in the final circuitry. Logic-level optimizations are performed on GTECH netlist and consists of two processes: structuring and flattening.