{"id":23685085,"url":"https://github.com/eonu/fpga","last_synced_at":"2026-01-25T20:09:20.584Z","repository":{"id":269244165,"uuid":"906823302","full_name":"eonu/fpga","owner":"eonu","description":"Hardware implementations for basic digital circuit designs in Verilog with a Xilinx Artix-7 FPGA chip on a Digilent Basys 3 development board.","archived":false,"fork":false,"pushed_at":"2025-01-29T02:52:35.000Z","size":2124,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-22T00:10:21.399Z","etag":null,"topics":["artix-7","basys3","circuits","digital-design","fpga","hardware","hardware-designs","hdl","simulation","testbench","verilog","vivado"],"latest_commit_sha":null,"homepage":"","language":"Verilog","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eonu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-12-22T02:27:57.000Z","updated_at":"2025-04-02T19:34:51.000Z","dependencies_parsed_at":"2024-12-22T05:17:23.497Z","dependency_job_id":"3ee1796d-6384-41e0-8c4c-4077e899c22a","html_url":"https://github.com/eonu/fpga","commit_stats":null,"previous_names":["eonu/fpga"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/eonu/fpga","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eonu%2Ffpga","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eonu%2Ffpga/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eonu%2Ffpga/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eonu%2Ffpga/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eonu","download_url":"https://codeload.github.com/eonu/fpga/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eonu%2Ffpga/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28757710,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T16:32:25.380Z","status":"ssl_error","status_checked_at":"2026-01-25T16:32:09.189Z","response_time":113,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["artix-7","basys3","circuits","digital-design","fpga","hardware","hardware-designs","hdl","simulation","testbench","verilog","vivado"],"created_at":"2024-12-29T20:53:45.951Z","updated_at":"2026-01-25T20:09:20.562Z","avatar_url":"https://github.com/eonu.png","language":"Verilog","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FPGA Circuit Designs\n\n**Hardware implementations for basic digital circuit designs applied to a [Digilent Basys 3](https://digilent.com/reference/programmable-logic/basys-3/start) development board with a [Xilinx Artix-7](https://www.amd.com/en/products/adaptive-socs-and-fpgas/fpga/artix-7.html) FPGA chip.**\n\nThese circuit designs are written in the [Verilog](https://en.wikipedia.org/wiki/Verilog) hardware description language, using the [Vivado Design Suite](https://www.amd.com/en/products/software/adaptive-socs-and-fpgas/vivado.html).\n\n---\n\n\u003cp\u003e\n  \u003csup\u003e\n    \u003cb\u003eContents\u003c/b\u003e:\n    \u003ca href=\"#what-is-this\"\u003eWhat is this?\u003c/a\u003e ·\n    \u003ca href=\"#what-is-an-fpga\"\u003eWhat is an FPGA?\u003c/a\u003e ·\n    \u003ca href=\"#steps-to-create-and-implement-hardware-designs-on-an-fpga\"\u003eSteps to create and implement hardware designs on an FPGA\u003c/a\u003e ·\n    \u003ca href=\"#circuits\"\u003eCircuits\u003c/a\u003e\n  \u003c/sup\u003e\n\u003c/p\u003e\n\n## What is this?\n\nI began this project as part of my exporation into FPGAs coming from a software engineering background with limited hardware and electrical engineering knowledge, and hope that it can be useful for other beginners.\n\nIf you do not have a background in digital design or hardware, I suggest at least partially reading [*Digital Design and Computer Architecture*](https://pages.hmc.edu/harris/ddca/ddca2e.html) by David Harris \u0026amp; Sarah L. Harris before getting started with FPGA development. The book provides a good foundation and is written very well, \neasy to follow and has a lot of follow-up exercises to test your knowledge.\n\nIf you want to follow along and try implementing some of the circuits, here are some suggestions:\n\n- Implement circuit designs in the order they are mentioned in this README.\n- If you don't have a development board yet, it is still possible to start with module design and simulation.\n- If you do have a board, always try out your modules on hardware — simulations aren't always the truth!\n- Other development boards should be fine as long as they have similar I/O to the Basys 3.\n- There is no need to stick to Verilog, feel free to try other HDLs.\n- Make sure to write a testbench or multiple for each module.\n- Compare your module designs with mine, but don't take them as gospel — I'm a learner too!\n- Feel free to create an issue to suggest new circuit designs that are suitable for beginners.\n\n## What is an FPGA?\n\nA [**field-programmable gate array (FPGA)**](https://en.wikipedia.org/wiki/Field-programmable_gate_array) is a reprogrammable integrated circuit consisting of:\n\n- **look-up tables (LUTs)** that can be programmed to implement any combinationial logic function,\n- **routing architecture (fabric)** that can be programmed to connect logic blocks (comprising LUTs) to I/O blocks.\nWith this flexibility FPGAs can be programmed to implement arbitrary hardware devices through the use of a hardware description language (HDL) such as Verilog.\n\nFor example, FPGAs can be used to implement:\n\n- low-latency network interfaces for receiving, manipulating and sending packets over different protocols,\n- video and image processors for applying transformations such as filtering and compression,\n- optimized inference pipelines for trained machine learning models,\n- and even microprocessors fully implemented in digital logic (called *soft microprocessors*).\n\nFPGAs are typically integrated into development boards such as the Digilent Basys 3 which consists of a Xilinx Artix-7 FPGA chip. Development boards provide:\n\n- on-board I/O devices such as push buttons, slide switches, LEDs, seven-segment displays, \n- ports for ethernet, VGA, HDMI, USB and PMOD connections,\n- on-board block RAM, digital signal processing cores and sometimes even CPU cores.\n\n\u003cp align=\"center\"\u003e\n\t\u003cimg width=\"700px\" src=\"assets/basys3.jpg\"/\u003e\u003cbr/\u003e\n\t\u003cem\u003eDigilent Basys 3 development board with a Xilinx Artix-7 FPGA chip (in the centre).\u003c/em\u003e\u003cbr/\u003e\n\t\u003csup\u003eImage courtesy of Digilent (from the \u003ca href=\"https://digilent.com/reference/programmable-logic/basys-3/reference-manual\"\u003eBasys 3 reference manual\u003c/a\u003e).\u003c/sup\u003e\n\u003c/p\u003e\n\n## Steps to create and implement hardware designs on an FPGA\n\nDespite some similarities, hardware design and implementation of digital circuits on an FPGA has a very different approach and process to software development.\n\n### 1. Module design\n\nDigital circuits are designed at this stage through the use of a HDL such as Verilog or VHDL.\nMost computer-aided design (CAD) tools such as Vivado can produce a schematic of the \nmodule for visual inspection.\n\n**Example**: Verilog module design and corresponding schematic for an 8-bit register file / SRAM.\n\n```verilog\n// 8-bit register file with one read port and one write port.\n// Uses 3-bit addresses (8 words) with 8-bit words, i.e. 64-bit capacity.\nmodule RegisterFile #(parameter ADDRESS_WIDTH = 3, WORD_WIDTH = 8) (\n    // 100MHz oscillator\n    input wire clk,\n    // Flag required for enabling data provided to the write port to be stored\n    input wire write_enable,\n    // Address of the register holding the word to read from the register file\n    input wire [ADDRESS_WIDTH-1:0] read_addr,\n    // Output word from the read port of the register file\n    output reg [WORD_WIDTH-1:0] read_data,\n    // Address of the register that a word should be written to in the register file\n    input wire [ADDRESS_WIDTH-1:0] write_addr,\n    // Input word provided to the write port of the register file\n    input wire [WORD_WIDTH-1:0] write_data\n);\n    // Create register space\n    parameter N_ADDRESSES = 2 ** ADDRESS_WIDTH;\n    reg [WORD_WIDTH-1:0] register_space [ADDRESS_WIDTH-1:0];\n    \n    // Initialize all registers to zero\n    integer addr;\n    initial\n        for (addr = 0; addr \u003c N_ADDRESSES; addr = addr + 1)\n            register_space[addr] = {WORD_WIDTH {1'b0}};\n    \n    // Asynchronous reads\n    always @(*)\n        read_data = register_space[read_addr];\n    \n    // Synchronous writes\n    always @(posedge clk)\n        if (write_enable)\n            register_space[write_addr] \u003c= write_data;\nendmodule\n```\n\nIn this case Vivado has correctly inferred that we have implemented a RAM module, \nand has represented the circuit as a single diagram element. \nIn practice, schematics will usually be more complex (as we will see later in the implementation stage).\n\n\u003cp align=\"center\"\u003e\n    \u003cimg width=\"700px\" src=\"assets/schematic.png\"/\u003e\n\u003c/p\u003e\n\n### 2. Behavioural simulation\n\nBefore designed modules are synthesized, implemented and programmed into an FPGA,\nbehavioural simulation lets us inspect a circuit design by building a *testbench* which \naccepts test input signals and allows us to compare expected outputs\nagainst simulated outputs through the use of *timing diagrams*.\n\nBehavioural simulation is somewhat analogous to writing unit tests for a modular software package.\n\n**Example**: Simulation test bench and corresponding timing diagram for the above register file module.\n\n```verilog\n`timescale 1ns / 1ps\n\nmodule TestRegisterFile #(parameter ADDRESS_WIDTH = 3, WORD_WIDTH = 8) ();\n    reg clk = 1'b0;\n    reg write_enable;\n    reg [ADDRESS_WIDTH-1:0] read_addr;\n    wire [WORD_WIDTH-1:0] read_data;\n    reg [ADDRESS_WIDTH-1:0] write_addr;\n    reg [WORD_WIDTH-1:0] write_data;\n    \n    RegisterFile CUT (\n    .clk(clk),\n    .write_enable(write_enable),\n    .read_addr(read_addr),\n    .read_data(read_data),\n    .write_addr(write_addr),\n    .write_data(write_data)\n    );\n    \n    always\n        // simulate a clock with a 10ns period (i.e. 100MHz)\n        #5 clk = ~clk;\n        \n    initial begin\n        // initial wait\n        #10;  \n        \n        // read data from address 0 - should be zero initialized\n        read_addr = 3'b000; #10;  \n        \n        // set data to be written to address 0 (on next clock tick after high enable)\n        write_addr = 3'b000; write_data = 8'b0000_1111; #12.5;\n        \n        // enable write to address 0 then disable\n        write_enable = 1'b1; #10;\n        write_enable = 1'b0; #10;\n        \n        // set data to be written to address 1 (on next clock tick after high enable)\n        write_addr = 3'b001; write_data = 8'b1111_0000; #12.5;\n        \n        // read data from address 1\n        read_addr = 3'b001; #10;\n        \n        // enable write to address 1 then disable\n        write_enable = 1'b1; #10;\n        write_enable = 1'b0; #10;\n        \n        // set data to copy from address 1 into address 2\n        write_addr = 3'b010; write_data = read_data; #12.5;\n        \n        // enable write to copy from address 1 into address 2\n        write_enable = 1'b1; #10;\n        write_enable = 1'b0; #10;\n        \n        // read from address 2\n        read_addr = 3'b010; #10;\n        $stop;\n    end\nendmodule\n```\n\n\u003cimg src=\"assets/simulation.png\"/\u003e\n\n### 3. Synthesis\n\nOnce tested through simulation, a circuit design can then be synthesized by mapping \nhigh level HDL code into the available hardware resources of the FPGA, called *primitives*. In other words,\nsynthesis converts (or *elaborates*) a circuit schematic into an FPGA *netlist*.\n\n### 4. Implementation\n\nWith the produced netlist from synthesis, implementation is the process of translating the described primitives\ninto the specific programmable logic blocks (*placement*) and fabric (*routing*) physically available on the FPGA.\n\nSpecifying constraints for a design is one of the key parts of implementation.\nThis involves mapping the external pins on the FPGA to the ports specified in HDL modules. \nThey also tell the tool which IO standard to use, as well as electrical circuit details such as \nvoltages, resistor types and slew rate.\n\nConstraints in Vivado are written in XDC files.\n\n**Example**: Constraint file showing a subset of pin connections, voltages and clock settings \ncorresponding to the register file HDL module ports.\n\n```tcl\n# Clock constraints\n# - Connect to pin W5 on the board\n# - Specify 3.3V voltage\n# - 10ns period (i.e 100MHz clock)\nset_property PACKAGE_PIN W5 [get_ports clk]\nset_property IOSTANDARD LVCMOS33 [get_ports clk]\ncreate_clock -period 10.000 -name clk -waveform {0.000 5.000} -add [get_ports clk]\n\n# Write port enable constraints\n# - Connect to pin V17 on the board (a slide switch)\n# - Specify 3.3V voltage\nset_property PACKAGE_PIN V17 [get_ports write_enable]\nset_property IOSTANDARD LVCMOS33 [get_ports write_enable]\n\n# Read port input address constraints\n# - Connect to pins W14, V15 and W15 (three slide switches)\n# - Specify 3.3V voltage\nset_property PACKAGE_PIN W14 [get_ports {read_addr[2]}]\nset_property PACKAGE_PIN V15 [get_ports {read_addr[1]}]\nset_property PACKAGE_PIN W15 [get_ports {read_addr[0]}]\nset_property IOSTANDARD LVCMOS33 [get_ports {read_addr[2]}]\nset_property IOSTANDARD LVCMOS33 [get_ports {read_addr[1]}]\nset_property IOSTANDARD LVCMOS33 [get_ports {read_addr[0]}]\n```\n\nOnce the hardware implementation is generated, we can inspect the actual logic that will be implemented on the FPGA board.\n\n\u003cimg src=\"assets/implementation.png\"/\u003e\n\n### 5. Bitstream generation\n\nThe final step of development is to generate a *bitstream*, which is a complete description of the \nlogic and routing necessary to implement the design on hardware. Bitstreams are typically vendor-specific, \nmeaning that each tool for FPGA development (e.g. Vivado) has a unique format and proprietary set \nof instructions for producing and representing bitstreams for hardware programming on supported FPGAs.\n\n### 6. Hardware programming\n\nWith a produced bitstream, the development board can be connected and the FPGA \nconfigured by pushing the bitstream to the device.\n\n## Circuits\n\nBelow are a selection of introductory circuits that are useful for learning basic FPGA development.\n\nEach circuit has its own project folder and set of subdirectories for project files:\n- `modules/`: Verilog design for the main module and any related modules used within the circuit.\n- `simulations/`: Simulation testbenches for behavioural testing of the module.\n- `constraints/`: XDC/TCL constraint files for placement and routing.\n\nEach circuit has more information on its own linked `README.md`, giving a high level description of the module as well as its expected inputs and outputs.\n\n### Combinational logic circuits\n\nCombinational logic circuits are time-independent, meaning that the output is purely a function of the current inputs.\nThese circuits are also described as memoryless or stateless, as they do not need to maintain any knowledge of past outputs.\n\nCombinational logic circuits are typically much simpler to program as timing and state is less of a concern during development and testing.\n\n- [x] [LED - Switch-powered](/projects/combinational/1-led-switch/)\n- [x] [LED - Switch-powered with AND gate](/projects/combinational/2-led-switch-and/)\n- [x] [Seven-segment display discoder](/projects/combinational/3-seven-segment-decoder/)\n- [x] [One-digit seven-segment display](/projects/combinational/4-one-digit-seven-segment-display/)\n- [x] [Arithmetic logic unit with LED display](/projects/combinational/5-arithmetic-logic-unit/)\n\n### Sequential logic circuits\n\nSequential logic circuits are circuits whose output is a function of their inputs, as well as past outputs. \nDue to the dependence on past outputs, sequential logic circuits require memory which is typically implemented\nin the form of *flip-flips* for *synchronous* circuits (synchronized with a clock signal).\n\nSequential logic circuits are usually synchronous for predictability and ease of design and testing, \nthough may be *asynchronous* in certain cases.\n\n- [x] [Four-digit seven-segment display](/projects/sequential/1-four-digit-seven-segment-display/)\n- [x] [Full seven-segment display](/projects/sequential/2-full-seven-segment-display/)\n- [x] [Arithmetic logic unit with seven-segment display](/projects/sequential/3-arithmetic-logic-unit-display)\n- [x] [Shift register - Switch-powered LED display](/projects/sequential/4-shift-register-switch/)\n- [x] [Shift register - Button-powered LED display](/projects/sequential/5-shift-register-button/)\n- [x] [Counter - Button-powered with variable increment/decrement and seven-segment display](/projects/sequential/6-variable-button-counter)\n- [x] [Divide-by-3 counter - Button-powered with seven-segment display](/projects/sequential/7-divide-by-3-counter)\n- [x] [Register file / SRAM](/projects/sequential/8-register-file-sram/)\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u0026copy; 2024-2026, Edwin Onuonga - Released under the \u003ca href=\"https://opensource.org/licenses/MIT\"\u003eMIT\u003c/a\u003e license.\u003cbr/\u003e\n  \u003cem\u003eAuthored and maintained by Edwin Onuonga.\u003c/em\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feonu%2Ffpga","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feonu%2Ffpga","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feonu%2Ffpga/lists"}