Designing the Future: Unraveling the Intricacies of PCB Innovation

In the realm of modern electronics, the printed circuit board (PCB) stands as a cornerstone of innovation, serving as the vital nervous system that brings technology to life. Within the intricate network of electronic components, the PCB plays a pivotal role, guiding the flow of data and power to actualize the brilliance of electronic devices we rely on daily.

 

Pioneering the Vision

 

At Addis PCB, we stand at the frontier of PCB design, where innovation meets precision, and creativity intertwines with functionality. Our journey is one that seeks to unravel the complexities of PCB innovation, pushing the boundaries of what’s conceivable and pondering the very essence of what it means to design the future.

 

Redefining Connectivity

 

Every connection on a PCB represents a pathway to possibility, where innovation meets practicality. We understand that each line, each pad, and each copper track is not just a conductor of electricity, but a conduit for ideas to flow, shaping the landscape of digital transformation. Through our meticulous design process, we pave the way for seamless connectivity, offering a canvas where innovation thrives.

 

Innovating with Precision

 

The intricacies of PCB design demand nothing short of precision. From the meticulous routing of traces to the strategic placement of components, our team of artisans and engineers work tirelessly to weave a masterpiece of circuitry. We embrace the challenge of navigating the evolving landscape of technology, infusing each design with the precision it deserves.

 

Harmonizing Form and Function

 

Elegance in design meets robust functionality in the world of PCB innovation. Our commitment to harmonizing form and function is unwavering, as we craft PCBs that not only power devices but enhance the user experience. Whether enabling complex electronic assemblies or lending sophistication to IoT solutions, our PCBs are a testament to the artistry and functionality we embody.

 

Cultivating Sustainable Innovation

 

In an age where sustainability is paramount, we tread the path of responsible innovation. From embracing eco-friendly materials to optimizing board layouts for efficiency, sustainability is woven into our design ethos. With a deep understanding of environmental impact, we oversee the creation of PCBs that meet the highest standards of responsible design.

 

At Addis PCB, our quest for unraveling the intricacies of PCB innovation unfolds as a testament to our unwavering commitment to pioneering the future. Through a fusion of creativity, precision, and responsibility, we continue to redefine what’s possible in the world of PCB design, paving the way for a future where electronic innovation knows no bounds.

 

Component placement in Printed Circuit Board (PCB) layout Design

The schematic design is done! What is the next big thing? 

Once the schematic design is complete, it is time to pass it to the next phase of the design stage to continue with the PCB layout design. All the efforts and know-how invested during the schematic design phase will be significantly compromised if the PCB layout design is not done correctly. Component placement is one of the foundational integrals of the PCB layout design process. It is more like placing the foundation of a house. There must be good planning and envisioning of what the final PCB should look like to have a board that is -Right the first time!   

PCB floor planning 

Component placement requires the PCB layout designer to envision various aspects of the design steps in advance. Before starting the placement of the component, the following important aspects of the design phases should be well thought out. As hard as it may be, these seven aspects of the design technics will need to be envisioned before and during the component placement stage. 

  1. Smooth routing (continuity of the circuitry flow)
  2. Functionality (components that have similar functions)
  3. Signal integrity
  4. Design for manufacturability (DFM)
  5. Design for testability (DFT)
  6. First time right!
  7. Design for usability. 

Starting with a block diagram will really help to plan out the PCB floor planning to an excellent kickstart. 

The size of the board is the decisive factor in how the component placement is going to be done. The bigger the board size the easier it is to plan out the component placement.  

When components are placed further apart, it gives room for routing and via-fan out. Being able to place all the components on the same side of the board will cut the assembly cost by a great deal. Placing parts on both sides of the PCB will be considered as an option when there is not enough space to place all the components on one side of the board. This will be the case in high-density interconnect (HDI) design and miniaturized board designs.    

Board size 

The first thing we must do is determine the board size. The board size is typically provided by the mechanical designer. A drawing exchange format (DXF) is a typical file format that the mechanical designer uses to communicate with the PCB layout designer. The DXF will contain board cutout, mounting hole locations, certain connector locations, switches, or LED (Light Emitting Diodes) locations, and any components that will need to be placed on a specific spot on the board. Also, heatsinks, sensors, and antennas can be part of the information that the Mechanical designer may include in the board outline. We can call or refer to these parts as fixed parts. It is always good to clearly communicate with the mechanical designer or anyone involved in this level of the design stage. It is this kind of clear communication that will allow the designers to determine and make sure that the board outline and the placement of any critical component are lined up with the enclosure, faceplate or housing of the final product.  

“Design is really an act of communication, which means having a deep understanding of the person with whom the designer is communicating.” Donald A. Norman 

Once the PCB layout designer takes care of the placement of the fixed parts, it is particularly important to communicate back to the mechanical designer. The best means of communication back to the mechanical designer may be using STEP model of the board along with the critical components which can be exported and handed over to the mechanical designer to double-check and verify the accuracy of the board size as well as the placement and clearance of the fixed components.  

Design rules 

Before getting into the full-scale component/footprint placement mode, it is critical to set up the design rules. Referring to and following IPC standards is key. How tight or relaxed the design rule should be is mainly determined by the size of the board and the number of components. Of course, there are various other factors that govern the placement of the components. Unless the board is exceedingly small and the component count is exceptionally high, it is always good to keep the design rule to be on the high end. The more the parts are spread the easier it is to route the board. Also, when it comes to assembly, it is much easier and less expensive to assemble a board with components placed spread out versus components that are close or touching each other due to lack of space. If the design is determined to be a high-density interconnect (HDI), then it is highly recommended to start by communicating with the contract manufacturer (CM) / assembly house at an early stage. Finding the capability of the contract manufacturer (CM) will help to fine-tune the design rules check (DRC) to that of the CM’s capability. It is always good to find out the minimum and maximum capability of the various CMs (Contract Manufacturer’s) design rules. This will allow the procurement team to have a pool of CMs to choose from. Once the design rules are set, it is good to make sure that the auto design rule check is turned on. Most or almost all layout design tools have the option to turn on and off the on-line DRC mode. Using online DRC while placing components from the start will save so much time. It is sometimes annoying to be forced not to temporarily place components very close to another component just to clear space for rearranging other component placement. But that should not be a reason to completely turn off online DRC. Even if online DRC is turned off for this purpose, it is very important to turn it on back and resume the component placement with online DRC turned on.     

A component placement done with design for manufacturability (DFM) in mind will give peace of mind to the entire team, including purchasing and the product development team.  

We are ready to start placing the components once the design rule is set up. Always use the highest component placement grid that is possible. Again, this is also determined by the board size and component size (the bigger the board size the higher the grid should be). The same thing with the components; the bigger the components, the higher the grid should be). But regardless of what; it is always advised to never place components without setting up a reasonable grid system based on an increment of 0.05mm (about 0 in). Using a grid system will also help ease routing among other things.           

Placing component by functionality 

Effective communication with the schematic designer is particularly important. Understanding the flow of the schematic even before starting the component placement will save a lot of unnecessary effort. Are there any critical components that need special attention? Are there components that are expected to get extremely hot? Is this a Radio Frequency (RF) design, analog design, digital design, and or mixed-signal design? Grouping components by their functionality can be a good starting point at the high level. This can be done outside of the board outline till it is determined what to place where. This will be a good time to color all the power (PWR) and ground (GND) nets as this will display on the ratsnest during the component placement.  

 

It is always challenging to figure out where to start the component placement, especially when there are quite a lot of components in a design. How do we determine where to start the component placement? To quote Desmond Tutu, “There is only one way to eat an elephant: a bite at a time.” Where do we even start that one bite? Start with components such as connectors, switches, LEDs (Light Emitting Diodes), and or any component that is determined to be placed at a certain location due to mechanical constraints. Mounting holes should also be placed in the early component placement stage. It is then an excellent strategy to continue placing components that are associated to the already placed components. It is at this point using the schematic as a guide will begin. The schematic is the source of guidance. It is also an innovative idea to first group components that need to be grouped together such as power supply, digital circuitry, RF circuitry, and analog circuitry together. By this time, the designer should determine if components will be placed on both sides of the boards or not. Using both sides of the boards for component placement will increase the cost of the assembly but it certainly helps to make the best of the space. Using both sides of the board for component placement will allow decoupling capacitors to be placed close to the power pins. If the board is a dense board, using both sides of the board for component placement will allow a smooth routing.  

It is unusual to expect placing components once and to be done with component placement. In a normal scenario, the PCB layout person will go back and forth placing, rotating, flipping, and moving components repeatedly. The only components that will be placed once and be kept untouched are the fixed components that the Mechanical Engineer provided with the board outline. Component placement is a time-consuming step of the process. As the saying goes – PCB design is 90% placement and 10% routing. Indeed, 90 percent of the PCB layout design is invested in component placement. If that is not the case, the routing process will be much more difficult and time-consuming.  

 

 Top side placement   

Bottom side placement 

PCB layout component placement requires the ability to visualize the various processes and steps simultaneously and throughout the component placement process.  

The following are important points to keep in mind while placing the components 

  1. Smooth routing space is required especially for critical routing nets. 
  2. Keeping enough space to fan out surface mount devices
  3. Having enough space for copper pour as needed for power and ground. 
  4. Enough space for placing silkscreen for each component. This is less important on the list. 
  5. It is important to orient pin one marking for the IC’s the same direction whenever possible.
  6. Keep components that are expected to dissipate a lot of heat away from other components and make sure there is enough space to place heat sink as well as place enough copper area on the board.

 

Component placement is time-consuming and requires a good understanding of the various disciplines that are associated with the flow of placing components. It is good to start with a simple design if doing the placement for the first time or without any experience.   

The fact that the software tools are becoming capable of viewing the board in 3D has made it much easier to visualize the board as if one is holding an assembled board.         

 

 

Making a RISC-V Processor

Well, it has been a while.

A few months ago, I challenged myself to make a drone from scratch and wrote a blog where I laid out the plan for this goal. The uniqueness of the project was that the flight controller of the drone runs not on an Arduino or Raspberry PI as it is done in similar projects. Instead, I wanted to build a RISC-V-based processor on FPGA and use this processor to run the flight controller program. I hereby want to update you on my progress.

A detailed description of the project can be found in the first blog. At a high level, this project involves 1) making a soft RISC-V processor (implementing the RTL), 2) making a custom FPGA PCB board and successfully loading the RISC-V processor into the FPGA, and 3) developing a flight controller program using C language and running it using the RISC-V processor inside the FPGA, and finally, 4) constructing and testing the drone. So far, I have completed the first task; that is, I have implemented and verified (to a certain extent) a 32-bit RISC-V processor.

In this blog, I discuss my design of the processor (the design is mostly inspired by the content in one of David Patterson’s book). I will also share a link to a detailed design diagram and the source code itself. My goal is to inspire and equip my readers to take on the same or similar projects and succeed.

What is a Processor?

A processor is a machine; it is a digital machine with two types of input. Its inputs are data and instruction. The input instruction tells the processor what to do with the input data. After manipulating the input data, the processor can modify its internal state and/or generate output data.

Embedded system processors (which we will focus on in this blog series), typically work with two distinct memories. The first is the Program Memory (PMEM) which carries the sequence of instructions the processor need to execute. The other is the Data Memory (DMEM), which carries the input and output data of the processor. Based on the sequence of instructions in PMEM, the processor reads and modifies the contents of DMEM. This is illustrated in Figure 1.

Figure 1. Processor Input and Outputs

Composition of a Processor

The processor block is typically composed of the following elements. We will discuss each subsequently.

  1. Registers
  2. Arithmetic Logic Unit (ALU)
  3. Control Unit (CU)
  4. Immediate
  5. Program Counter (PC)
Registers

Registers are the internal memory of the processor. The processor can operate only on data that is stored in registers; the processor does not manipulate data directly at the DMEM. Instead, the data is first copied from DMEM to registers through load instructions. The direct output of a processor operation is written to one of the registers before it is copied to DMEM through store instructions.

RISC-V instruction set manual specifies the processor to have 32 registers. In the 32-bit version of the standard, each of these registers have 32-bit width. The first register is specified to contain 0 always. As shown in Figure 2, an instruction can read one or two registers (source_0_idx and source_1_idx) and can write to one register (dest_idx).

Figure 2. RISC-V Registers

Before we move forward, it may be good to see what a RISC-V instruction looks like. RISC-V is a processor following the RISC-V instruction set manual specification. The instruction manual outlines and defines a set of instructions to be supported by a RISC-V processor. In other words, a specification compliant RISC-V processor can correctly run a program that is generated by a RISC-V compiler.

There are multiple versions of RISC-V processors. The basic 32-bit RISC-V instruction set involves more than 40 instructions (see the full list). As shown in Figure 2, each instruction is represented by 32 bits; and within these 32 bits, the instruction packs the opcode (opcode and func3) which determines the function of the instruction, the index of register operands (rs1 and rs2) which determine the operands of the instruction, destination register index (rd) where the output is written to, and a constant (imm) which is an additional operand.

An instruction format defines how the different components of the instruction are arranged within the available 32 bits. As shown in Figure 3, 32-bit RISC-V instructions use one of the shown six formats.

Figure 3. RISC-V instruction formats

As an example, you may consider the RISC-V instruction ADDI rd, rs1, imm. This instruction adds the content of register rs1 with imm and stores the sum into register rd. If the actual instruction is ADDI 5,0,10, then the processor is instructed to add 10 to the contents of register 0 (which is always 0). After the processor finishes executing this instruction, we should find 10 at register 5.

ADDI follows the “I” (the second row in Figure 3) instruction format (see here). The opcode of ADDI is 0x13 (in hex), and the func3 value is zero. Accordingly, the 32 bit binary representation of ADDI 5,0,10 is construction in Table 1.

Table 1. Binary Representation of ADDI 5,0,10

Instruction Element Bit index Value (Hex) Value (Binary)
Opcode [6:0] 0x13 001 0011
rd [11:7] 0x5 0 0101
func3 [14:12] 0x0 000
rs1 [19:15] 0x0 0 0000
imm [31:20] 0x00B 0000 0000 1011
Full Instruction (Binary) 0000 0000 1011 0000 0000 0010 1001 0011
Immediate Block

The immediate block extracts the constant operand from an instruction (except for “R” instruction which does not contain imm). The immediate block first reads the opcode and func3 (which are at fixed bit locations regardless of instruction format (see Figure 3), and then based on the value of the opcode it infers the format and the bit locations of imm.

Arithmetic Logical Unit (ALU)

As discussed above, a RISC-V instruction contains an opcode, the list of operands, and a destination register address (if the instruction involves a register write). One of the operands is always a register and the other one can be a register or an immediate constant.

The ALU carries out arithmetic or logical operation on the operands. The opcode determines which type of arithmetic or logical operation the ALU should conduct. The ALU can perform adding, subtracting, anding, oring, xoring, logical shifting, and arithmetic shifting (see a complete list of instructions here). The ALU outputs the outcome of the operation and a set of flags.

Besides the main output, ALU generates a set of flags that indicate aspects of the operation outcome. The flags indicate if the output is zero, or negative, or positive, or if there was an overflow.

Figure 4. Contents of an Instruction and Interconnection between Registers, Immediate Block and ALU

Control Unit (CU)

The CU can be considered the master block in the processor. Its main task is to extract the opcode and func3 (if any) which are always located at the same bit locations regardless of instruction format (see Figure 2). This opcode is an input to the ALU and the immediate block. More importantly, the CU generates control signals that configure the processor according to the function of the input instruction.

For example, one RISC-V instruction is the load instruction. The load instruction copies the content of a DMEM address into one of the registers. Accordingly, when the CU sees a load instruction, it raises a register_wr_en (enable for writing into one of the registers). The other set of RISC-V instructions is the store instruction set. The store instructions do the opposite of what load instructions do; they copy the content of a register into a given DMEM location. Hence, when the CU sees a store instruction, it lowers register_wr_en and raises data_mem_wr_en (enable for writing into DMEM). Figure 4 shows some of the control signals generated by the CU.

Figure 5. Control Unit Input and Output (partially)

Program Counter (PC)

As discussed above, instructions are sequentially stored in PMEM. Obviously, the running program contains more than one instruction. Hence, the processor should know where from PMEM to read the next instruction. The Program Counter (PC) stores the next read address of the PMEM.

In 32-bit RISC-V, each instruction spans 32 bits (4 bytes). Therefore, the processor increments the PC by 4 at every instruction. However, if the program encounters a branch, the PC is overwritten with the landing address of the branch instruction.

Figure 6. Updating the Program Counter

Putting it Together and Pipelining

We are now ready to put all the elements together. Figure 7 shows a simplified version diagram of the processor we are building in this project. First, the instruction is read from PMEM. Then, this instruction is decoded inside the CU and the Immediate blocks. In parallel, register operands are read out from the register block. After register reads and instruction decode, the instruction is executed in ALU. The next stage involves DMEM read or write, and the final stage involves register write step.

Figure 7. Simplified sketch of a Full RISC-V Processor

As you can elude from Figure 7, the processor elements are intentionally organized into five stages; this is done so to allow pipelining. Pipelining allows the processor to start processing the next instruction before it finishes processing the current one. For example, when the current instruction is in stage 2 (Decoding stage), the processor can go ahead and read PMEM for the next instruction, without interfering with the execution of the current instruction. Otherwise, the PMEM read stage (stage1) unnecessarily remains idle until the current instruction goes through all the five stages – which leads to inefficiency and slowness.

Figure 8 illustrates the benefits of pipelining using two instructions. It shows that pipelining can provide a 40% reduction in cycle count. The performance difference between pipelining and not pipelining increases along with the total number of instructions. For example, if 1000 instructions are considered, the unpipelined design would take 5000 cycles to finish while pipelined design would take as small as 1004 instructions – a whapping 5x difference. Pipelining is a must in a processor design.

Figure 8. Benefits of Pipelining

Actual Design

Before discussing the intricacies of pipelining, I want to show the actual (fully detailed) design. You can find the lucid chart block diagrams here (free login to lucid chart is required to view them). One can understand the detailed (seemingly complicated) design easily after understanding the simplified sketch shown in Figure 7.

Below are listed highlights of the actual design. I will not attempt to describe the full detail here – one can get the complete detail by looking at the block diagrams and the source code.

Two Cycles per Stage

PMEM and DMEM are implemented using Block RAM IP from Xilinx. The read and write to this memory costs two clock cycles – this means the instruction fetch and DMEM RD/WR stages of the pipeline last two cycles (not only cycle as shown in the illustration in Figure 8). To make the pipeline consistent, all the other stages (Decode, ALU and Reg WR) are also designed to span two cycles.

Every Signal is Pipelined

Pipelining applies to all signals – a signal crossing from one stage to another should do so with two-cycle delay. To illustrate this point, consider the JAL rd, imm instruction. This instruction causes an unconditional jump to address PC + imm, and stores PC + 4 into register rd. PC originates from stage1, but it is written to rd at stage 5. The PC originates from stage1, but the writing to rd register happens at stage5. Hence, the PC signal must be propagated through the stages until it reaches stage5. Hence, as shown in Figure 9, the value that is written to rd is PC delayed from 6 cycles ago plus 4. Similarly, the rd address and the register write enable which are both obtained at stage2 need to be propagated through the pipeline.

Figure 9. Every signal must be pipelined

First Kind of Data Hazard

Pipelining becomes difficult if two consecutive instructions have dependencies on each other. For example, consider the following consecutive instructions:

  1. ADD 5,0,1 (Add contents of register 1 to 0 and store the result in register 5)
  2. ADD 6,0,5 (Add contents of register 5 to 0 and store the result in register 6).

The actual adding (in ALU) of the second instruction assumes register 5 to be already updated by the first instruction. As shown in Figure 10, the second instruction ALU occurs before the register update from the first instruction is fulfilled. Unaddressed, this would result in incorrect program behavior.

To detect a data hazard, the processor needs to check if the operand registers of the current instruction are the same as the destination register of the previous instruction. Accordingly, data hazards can be detected as soon as the instruction from the current instruction is fetched.   As shown in Figure 10, the solution to this kind of pipelining hazard is called forwarding (see here for further reading). Forwarding leverages the fact that the value to be written to register 5 is already available at the end of the ALU stage of the first instruction. It just must propagate through the pipeline to be written to the register. Accordingly, if the ALU operation of the second instruction takes the ALU out of the first instruction instead of the current register readout, it would use the correct content of register 5. This mechanism is called forwarding. When this kind of hazard is detected, the ALU takes its input from its own output (the ALU output of previous instruction).

Figure 10. First kind of data hazard, and addressing it using forwarding

Second Kind of Data Hazard

The first kind of hazard is (relatively) benign one for that it can be addressed without stalling the pipeline. The second kind of data hazard however requires a more elaborate mechanism to be addressed. The second kind of data hazard occurs if current ALU-using instruction depends on memory read in the previous instruction. For example, consider the following consecutive instructions:

  1. LW 5,0,10 (Read DMEM at address 10 and store the outcome in register 5)
  2. ADD 6,0,5 (Add contents of register 5 to 0 and store the result in register 6).

As shown in Figure 11, the value going to register 5 is not even available by the time the second instruction is ready to do the adding inside the ALU. Accordingly, forwarding is not possible. In this design, this hazard is handled by injecting no-operation (NoP) instruction followed by a repeat of the second instruction. Accordingly, this hazard slows down the pipeline by 2 stages (4 clock cycles).

Figure 11. Second kind of data hazard, and addressing it by instruction repeat

Control Hazard (Caused by Branching)

The other type of pipeline hazard is caused by conditionally branching instructions. In such instructions, the processor does not whether to take the branch until the ALU computes the branch condition and updates the flags. However, by then two other instructions would be already in the pipeline. If the branch is not taken, executing the processor can carry on without interrupting the pipeline. However, if the branch is to be taken, the processor should somehow stall the execution of the two following instructions which are already in the pipeline

Figure 12. Control hazards and how to address it

For example, consider the following instructions.

  1. BEQ 5,4,20 (If contents of register 5 and 4 are equal, branch to the instruction that is 20 bytes aways – or after 5 instructions )
  2. ADDI 6,0,5 (Put 5 in register 6).
  3. ADDI 7,0,5 (Put 5 in register 7).
  4. ADDI 8,0,5
  5. ADDI 9,0,5
  6. ADDI 6,0,8 (Put 8 in register 6).

While executing the first instruction, if the processor finds that the content of registers 5 and 4 are the same; then the processor in theory should execute the 6th instruction, not the second and the third. But the hazard is from the fact that the second and third instructions will already be in the pipeline. In this design, this hazard is handled by allowing the second and third instructions to carry on in the pipeline, but DMEM and register write in the last two stages are disabled for the following two instructions if the branch needs to be taken. The 6th instruction is fetched as soon as the ALU updates the flags in the branch instruction. Because of this hazard, the processor will waste 2 pipeline stages or 4 cycles – and that is so only if the branch needs to be taken.

Verification

The source code of this implementation can be found in our GitLab repository. After the implementation, the code is tested through a verification test bench which you may find under “tb” folder. All RISC-V instructions (except sync, system, and counter instructions) were tested individually with some randomized test tasks. In particular, the register operands and the immediate values used in the tests were randomized to improve test quality and coverage. In addition, 8 other tests were added to test data and control hazards handling logics. All these tests (45 in total) are now passing.

Next Steps

The next step in this project involves testing the processor with realistic codes originating from actual compilers. In addition, we will be making a PCB board for the FPGA which will be hosting the RISC-V processor. I will come back with an update once these steps are completed. It will all be exciting!!!

 

 

 

 

Digital Hardware Implementation: Let’s Make an Ethiopian Drone

By: Eyosias Yoseph Imana, PhD.

I was a middle-schooler when mobile phones were first introduced to Ethiopia, my home country. Besides feeling excited from seeing a mobile phone for the first time, I remember wondering if I will ever be able to understand how the thing works. I also wondered if I would be able to make one “when I grow up.”

If you are reading this blog, I bet you have had such kinds of thoughts at some point. You are not satisfied in being a mere consumer of technology, you want to join the makers club. Well, I hope this blog series will inspire and equip you to convert your ideas into prototypes – and possibly into a viable commercial product. My vision is to see many makers come out of sub-Saharan Africa – and hence, the target audience of this blog series are all the aspiring and current makers/entrepreneurs from the region.

A little about myself; my name is Eyosias Yoseph. I have been with the semiconductor industry in USA for almost 7 years. Before joining the industry, I was first a PhD student, and later a postdoc at Virginia Tech. I completed my MSc from Florida Tech, and BSc from Bahir Dar University. All my degrees are in electrical engineering, and my focus areas include wireless communications, signal processing, and digital system implementation.

In this blog series, I plan to chronicle the journey I am now starting to make a quadruple drone from scratch and teach what I know about digital implementation along the way. I note that making a drone from scratch is not new – folks have successfully built drones from scratch using Arduino (see here and here). The uniqueness of my effort will be in part because instead of Arduino I will be using a custom RISC-V processor implemented on a custom FPGA board. In fact, my goal (at least for now) is to learn and teach how to make things, not to contribute anything novel.

I am not sure if my drone will successfully fly, but I am sure that I will be learning quite a bit along the way and will be sharing those learnings in the upcoming blogs. Besides sharing my updates, I will include a video along with each blog where I cover important concepts/techniques/tools I use to do this project. Stay tuned!!

Block Diagram

The block diagram of the envisioned system is as follows. I plan to custom design and implement much of the yellow block in the middle of the diagram – that is, I will be making a PCB board for the FPGA, a RISC-V processor inside the FPGA, and a flight controller software to run on the processor.

This project involves hardware, software, and mechanical developments. A high-level roadmap of this project is as follows:

1. Hardware development
  • Processor design and implementation: I first plan to paper-design a RISC-V based processor and then implement its RTL using Vivado webpack from Xilinx (it is free). The RTL will be written using System Verilog.
  • RTL verification: I then plan to write unit and integrated testbenches (again using System Verilog) and test the processor design extensively using simulations. I will be using the simulator built in Vivado. To create randomized testing, and automation, I plan to use python scripts which call Vivado’s internal commands (called TCL).
  • Validation using real C program: Once the processor RTL is ready (passes most verification tests), I will make a simple C program and compile it with GNU RISC-V cross-compiler (download here). I will then load the executable binary generated by the compiler into the RTL simulator and run to see if the processor produces the expected results.
  • PCB design and fabrication: I will then make a PCB board containing an FPGA where the processor can be implemented. The PCB board is likely to contain a Xilinx’s Spartan-6 FPGA and will be designed using KiCad (download here).
  • PCB bring-up: Once the board is fabricated it needs to be brought up (may need two or three iterations to get a usable board)
2. Software development
  • Hardware model development: bare-metal programming is bug-prone because the programmer must deal with the hardware details which can be slipped up easily. To facilitate debug during flight controller software development, we will be first developing a C based model for the hardware. This model will be verified against RTL. Once verified, it will be used to bring up the final software.
  • Flight controller software development: The flight controller program will be developed in C on top of the hardware model first, and then on the actual hardware. As mentioned earlier I will be using GNU RISC-V cross-compiler.
  • Bring-up
  • Fly the drone!!!

It can be noted all the tools I plan to use in this project are open-source and/or free. Anyone can follow along and contribute to this project. I will be hosting the project in GitLab with public access. The only monetary expense in this project will be coming from PCB board fabrication, and the purchase of mechanical and electrical parts for the drone.

GitLab Repository

I named this project DESTINY, it is hosted at this GitLab.

Why RISC-V?

Say an Ethiopian company plans to make and sell a portable electronic device that can translate between the local languages in real-time (example, from Afan Oromo to Amharic and vice versa). Such device inevitably has a built-in processor – almost all electronic devices (ranging from a simple digital watch to a space shuttle are build with at least one processor).

The said company can choose one of the following routes to obtain a processor technology to put into its new device:

  1. Using another company’s processor chip: The company can choose to use a third-party processor chip (for example, from Intel, or Texas Instruments, or etc) which may be a good starting place but obviously expensive.
  2. Using another company’s processor IP: The company may license a processor design from a third party (for example, from ARM as every major companies including Apple and Qualcomm are doing) and customize and fabricate the processor chip. But this also comes with a hefty licensing fee.
  3. Making its own processor from scratch: Besides the riskiness of this route, it is not guaranteed to be cheaper than the first two. Making a new processor from scratch would also mean making a new build/compile toolbox which cannot be achieved without a significant Non-Recurring Expense (NRE).

Hence, all the above three options are expensive. The first two routes also indicate a perpetual technological dependence on western companies which may not be a wise choice in the current geopolitical environment. For example, what if a trade war makes it impossible for western companies to supply chip or IP to Ethiopia? Well, that is not an impossibility anymore.

RISC-V is a 4th alternative – and the most optimal choice in my opinion. RISC-V is an open processor instruction set standard. It is an open standard, which means, anyone can make a processor based on this instruction set without paying licensing fees to a third party. Furthermore, there exists GNU compiler toolbox for RISC-V already. It is also new and has the potential to grow and dethrone ARM from its prevalence in the embedded processor world in the coming years. If we are early players in RISC-V, not only we can use it to make our own products, but we may also become key RISC-V chip and IP suppliers for the global market (why not?). For these reasons, I think the nascent Ethiopian computer/software engineering community should take the RISC-V opportunity seriously.

Getting Started with RISC-V

Are you interested to know more about RISC-V? Below are important links to learn further about RISC-V.

Today’s Lesson: Building a Bare-metal C Program

Before I close today’s blog, I invite you to watch the following this video where I teach about bare-metal programming using GNU’s RISC-V toolbox.