<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>samienr - Projects</title>
    <subtitle>Electrical Nerd + Digital Artist</subtitle>
    <link rel="self" type="application/atom+xml" href="https://samienr.com/tags/projects/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://samienr.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-12-29T00:00:00+00:00</updated>
    <id>https://samienr.com/tags/projects/atom.xml</id>
    <entry xml:lang="en">
        <title>Designing a CPU From Scratch, Part 3: Datapath</title>
        <published>2025-12-29T00:00:00+00:00</published>
        <updated>2025-12-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Samien Rahman
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samienr.com/blog/designing-a-cpu-03/"/>
        <id>https://samienr.com/blog/designing-a-cpu-03/</id>
        
        <content type="html" xml:base="https://samienr.com/blog/designing-a-cpu-03/">&lt;p&gt;Last time, we finished off with a very barebones set of components
for our RISC-V core. Now we can begin with the first half of most interesting part
of this process: connecting the datapath and creating the control signals.&lt;&#x2F;p&gt;
&lt;p&gt;Microarchitectures are typically divided into two parts: a datapath and a
control unit. The datapath consists of structures that hold the architectural
state of the machine (like those we made in Part 2 of these blogs). It also
houses a bunch of combinational logic which is used to process that state
information and create new state information for the next state. This is what
we will be making in this blog entry.&lt;&#x2F;p&gt;
&lt;p&gt;This is all driven by the control unit, which receives state information from
the datapath, then tells the datapath what to do using control signals, such
as write enables, mux selectors, and any other &quot;decisions&quot; our datapath logic
has to make. We will figure out what control signals we need in Part 4 after
creating the datapath.&lt;&#x2F;p&gt;
&lt;p&gt;We will begin by putting together the components we made last time,
in addition to making some smaller components that will be needed
to make these connections. In the next part we will create a set of control
signals and a control unit to assert appropriate signals for each instruction.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;pipeline-registers&quot;&gt;Pipeline Registers&lt;&#x2F;h1&gt;
&lt;p&gt;Let&#x27;s start by taking a look at the components we made in &lt;a href=&quot;https:&#x2F;&#x2F;samienr.com&#x2F;blog&#x2F;designing-a-cpu-02&#x2F;&quot;&gt;Part 2&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;figure&gt;

	&lt;img class=&quot;
			
			
			
			
                        
		&quot;
		
		src=&quot;basicComponents.png&quot; &#x2F;&gt;
	


&lt;figcaption&gt;The components we made in Part 2: PC, ALU, instruction and data memory&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Since this is a pipelined machine, before we wire everything up, we need
to think about what stage we want each component to be used in. Each instruction
will propagate through all five stages of the pipeline: instruction fetch (&lt;code&gt;IF&lt;&#x2F;code&gt;),
instruction decode (&lt;code&gt;ID&lt;&#x2F;code&gt;), address generation&#x2F;execute (&lt;code&gt;AGEX&lt;&#x2F;code&gt;), memory access (&lt;code&gt;M&lt;&#x2F;code&gt;),
and writeback (&lt;code&gt;WB&lt;&#x2F;code&gt;). Since an instruction can only occupy one stage at a time,
we need a way to keep track of data and control signals for each instruction
as it traverses the pipeline stages. We will place registers between each stage
that will store whatever information an instruction may need as it is processed.
Now, whenever we want to place a component into the datapath, we need to consider
what stage it would best belong in.&lt;&#x2F;p&gt;
&lt;p&gt;We know that the instruction memory must be accessed using the address in the PC
during &lt;code&gt;IF&lt;&#x2F;code&gt;, so we will place them there. The register file will need to be accessed
in &lt;code&gt;ID&lt;&#x2F;code&gt; so that source registers are ready to be accessed by the &lt;code&gt;AGEX&lt;&#x2F;code&gt; stage. The
data memory will obviously need to be accessed during the &lt;code&gt;M&lt;&#x2F;code&gt; stage.&lt;&#x2F;p&gt;
&lt;figure&gt;

	&lt;img class=&quot;
			
			
			
			
                        
		&quot;
		
		src=&quot;pipelineRegs.png&quot; &#x2F;&gt;
	


&lt;figcaption&gt;Each of the aforementioned components closest to the pipeline registers they will access the most&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Now we will go through each pipeline stage and add whatever components are needed
to support every instruction in the RV32I instruction set.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;fetch&quot;&gt;Fetch&lt;&#x2F;h1&gt;
&lt;p&gt;The fetch stage is mostly already mostly done. The PC simply requests the I-cache
for whatever instruction is at the PC&#x27;s address. The I-cache retrieves the instruction
and latches it into the &lt;code&gt;IF&#x2F;ID&lt;&#x2F;code&gt; register. Additionally, the PC must update each with
each instruction. In most cases it is simply incremented by 4, but branch and jump
instructions will cause the PC to take another value. For this reason, we need to mux
in all its possible next values. The target addressses for branches and &lt;code&gt;jal&lt;&#x2F;code&gt; are
computed the same way, so those can share a mux input, and &lt;code&gt;jalr&lt;&#x2F;code&gt; will use the ALU
output, so that will also need its own mux input.&lt;&#x2F;p&gt;
&lt;p&gt;Now we can update the PC, however the PC does &lt;em&gt;not&lt;&#x2F;em&gt; change every cycle. As we
will discuss in the next blog, there are cases where pipeline stages may stall. When
this happens, we must not update the PC, hence we need to note that we need a control
signal to indicate whether or not the PC should be updated in a cycle.&lt;&#x2F;p&gt;
&lt;p&gt;And now that I&#x27;ve mentioned stalling, we might as well include some abstract hardware
for that too.&lt;&#x2F;p&gt;
&lt;figure&gt;

	&lt;img class=&quot;
			
			
			
			
                        
		&quot;
		
		src=&quot;IF.png&quot; &#x2F;&gt;
	


&lt;figcaption&gt;Instruction fetch stage&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;h1 id=&quot;decode&quot;&gt;Decode&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;control-unit&quot;&gt;Control Unit&lt;&#x2F;h2&gt;
&lt;p&gt;The decode stage takes the instruction fetched from the previous stage and figures out
what the rest of the datapath should do with the instruction. Part of this involves
producing the appropriate control signals for the instruction. Thus, the control unit
belongs in this stage. In our case, the control unit is really just a big ROM where each
entry is the set of control signals for a particular type of instruction. Since we don&#x27;t
yet know which control signals are needed, we&#x27;ll design the datapath components first,
assuming the control unit will provide the necessary signals. We&#x27;ll specify the actual
control signal values once the datapath requirements are clear.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;immediate-generator&quot;&gt;Immediate Generator&lt;&#x2F;h2&gt;
&lt;p&gt;Since the immediate bit derivations are different for each instruction type, the value generation
will use separate logic for each type of instruction. Depending on the instruction type, we will
then select which decoding scheme we will use for the current instruction. &lt;em&gt;&quot;How will we choose?&quot;&lt;&#x2F;em&gt;
you may ask &lt;em&gt;&lt;small&gt;(or not)&lt;&#x2F;small&gt;&lt;&#x2F;em&gt;. &lt;em&gt;This,&lt;&#x2F;em&gt; is the first place we will need to use a control
signal. The control unit will look at the instruction type and determine what the appropriate selector
bits for the immediate value mux should be. The correct value will come out of the mux and be latched
into the &lt;code&gt;ID&#x2F;AGEX&lt;&#x2F;code&gt; register.&lt;&#x2F;p&gt;
&lt;p&gt;As for the implementation, it&#x27;s just a matter of checking the opcode and then bit swizzling everything
together, then sign extending:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Instruction Type&lt;&#x2F;th&gt;&lt;th&gt;Expression&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;I-type&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;{ {20{inst[31]}}, inst[31:20] }&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;S-type&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;{ {20{inst[31]}}, inst[31:25], inst[11:7] }&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;B-type&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;{ {19{inst[31]}}, inst[31], inst[7], inst[30:25], inst[11:8], 1&#x27;b0 }&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;U-type&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;{ inst[31:12], 12&#x27;h000 }&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;J-type&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;{ {11{inst[31]}}, inst[31], inst[19:12], inst[20], inst[30:21], 1&#x27;b0 }&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;register-file&quot;&gt;Register File&lt;&#x2F;h2&gt;
&lt;p&gt;Since RISC-V formats all its instruction types in a way such that the addresses of the
source and destination registers are always in the same bit fields, pulling data out of
the register file is trivial. To get our source registers, we simply need to get &lt;code&gt;IR[19:5]&lt;&#x2F;code&gt;
for &lt;code&gt;rs1&lt;&#x2F;code&gt; and &lt;code&gt;IR[24:20]&lt;&#x2F;code&gt; for &lt;code&gt;rs2&lt;&#x2F;code&gt;. By the end of the clock cycle, these registers should
be fetched and latched in for the &lt;code&gt;AGEX&lt;&#x2F;code&gt; stage. As for the destination register, whatever
instruction is currently in the decode stage is not going to be ready to write back results
just yet. In fact, the instructions that are ready to write back results will be those in the
&lt;code&gt;WB&lt;&#x2F;code&gt; stage. Because of this, we&#x27;re not going to connect &lt;code&gt;we&lt;&#x2F;code&gt; or any of the &lt;code&gt;rd&lt;&#x2F;code&gt; inputs quite yet.
We&#x27;ll come back to this later once we hit a stage where instructions are ready to write back their results.&lt;&#x2F;p&gt;
&lt;figure&gt;

	&lt;img class=&quot;
			
			
			
			
                        
		&quot;
		
		src=&quot;ID.png&quot; &#x2F;&gt;
	


&lt;figcaption&gt;Instruction decode stage&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;h1 id=&quot;address-generation-execute&quot;&gt;Address Generation&#x2F;Execute&lt;&#x2F;h1&gt;
&lt;p&gt;Like the name suggests, this stage does a few things, including:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;computing results for arithemic and logical operations&lt;&#x2F;li&gt;
&lt;li&gt;generating target addresses for memory accesses and branch&#x2F;jump targets&lt;&#x2F;li&gt;
&lt;li&gt;producing conditional flags&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;execution&quot;&gt;Execution&lt;&#x2F;h2&gt;
&lt;p&gt;In Part 2, we discussed everything the ALU does. All of that happens here. All we have to do is
determine what the ALU&#x27;s operands are and wire it up. Most instructions will simply involve using
two source registers. In these cases,  &lt;code&gt;ALU_A&lt;&#x2F;code&gt; and &lt;code&gt;ALU_B&lt;&#x2F;code&gt; will be &lt;code&gt;rs1&lt;&#x2F;code&gt; and &lt;code&gt;rs2&lt;&#x2F;code&gt;, respectfully.&lt;br &#x2F;&gt;
However, that is not all. I and U-type instructions use immediate values instead of &lt;code&gt;rs2&lt;&#x2F;code&gt;, so that
will need to be muxed. Additionally, the &lt;code&gt;auipc&lt;&#x2F;code&gt; instruction uses the PC instead of &lt;code&gt;rs1&lt;&#x2F;code&gt;, so that
will also need to be muxed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;address-generation&quot;&gt;Address Generation&lt;&#x2F;h2&gt;
&lt;p&gt;All address generation comes from adding the PC with an offset which comes from the instruction&#x27;s
given immediate value. Since our immediate values were decoded and generated in the &lt;code&gt;ID&lt;&#x2F;code&gt; phase,
they are ready to use in the &lt;code&gt;AGEX&lt;&#x2F;code&gt; stage. We can trivially pull the immediate values values from
the &lt;code&gt;ID&#x2F;AGEX&lt;&#x2F;code&gt; registers and then add that to the PC to get the correct PC offset. This is the target
address for branches, jumps, and memory loads&#x2F;stores.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;jalr&lt;&#x2F;code&gt; instruction is unique in that its target address comes from adding an immediate value
to a source register, meaning its address generation must come from the ALU if we don&#x27;t want to add
more hardware. Additionally, RV32I requires that addresses generated by the &lt;code&gt;jalr&lt;&#x2F;code&gt; instruction are
half-word aligned, so the last bit must be 0. This is due to maintaining compatibility with
RV32C-capable machines.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;condition-codes-flags&quot;&gt;Condition Codes&#x2F;Flags&lt;&#x2F;h2&gt;
&lt;p&gt;To determine whether or not a branch should be taken, &lt;code&gt;rs1&lt;&#x2F;code&gt; and &lt;code&gt;rs2&lt;&#x2F;code&gt; are compared according to
what we mentioned in Part 2. Recall that when we made the ALU, the primary output was the result
of the arithmetic or logical operation. But the secondary outputs were the &lt;code&gt;zero&lt;&#x2F;code&gt;, &lt;code&gt;lt&lt;&#x2F;code&gt; and &lt;code&gt;ltU&lt;&#x2F;code&gt;
signals. We will use these as discussed in Part 2, along with another control signal to generate
the PCMUX signal used in the &lt;code&gt;IF&lt;&#x2F;code&gt; stage. The reason we need another signal is because of the jump
instructions. Since they are unconditional, we need a way to change our address no matter what.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;control-hazard&quot;&gt;Control Hazard&lt;&#x2F;h2&gt;
&lt;p&gt;Because it takes until the &lt;code&gt;AGEX&lt;&#x2F;code&gt; stage to determine what the next PC should be, this introduces
what is called a hazard: What do we do with the two instructions fetched immediately after a jump
or branch? We need a way to tell our machine to ignore those instructions in case the wrong
instructions were fetched. This is a control hazard and will be handled later in Part 4 after we
have a mostly complete control unit. This is because we want to have the entire big picture in mind
when managing hazards.&lt;&#x2F;p&gt;
&lt;figure&gt;

	&lt;img class=&quot;
			
			
			
			
                        
		&quot;
		
		src=&quot;AGEX.png&quot; &#x2F;&gt;
	


&lt;figcaption&gt;Address generate&#x2F;execute stage&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;h1 id=&quot;memory-access&quot;&gt;Memory Access&lt;&#x2F;h1&gt;
&lt;p&gt;The memory stage of the pipeline is quite simple in terms of hardware with our level of abstraction.
We only need to supply the data memory unit with an address and some control signals for write accesses.
If the current instruction is a load instruction, then the data of whatever is at the supplied address
must be latched for the &lt;code&gt;WB&lt;&#x2F;code&gt; stage.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;ll also need a control signal to ensure that accesses are processed
in an appropriate manner for the right data size for each instruction.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, since memory can
take several cycles to be ready, we will need to ensure that we know whether or not we are ready to move
the instruction to the next stage yet or if we need to wait a little longer for the memory to be ready.&lt;&#x2F;p&gt;
&lt;figure&gt;

	&lt;img class=&quot;
			
			
			
			
                        
		&quot;
		
		src=&quot;M.png&quot; &#x2F;&gt;
	


&lt;figcaption&gt;Memory access stage&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;h1 id=&quot;writeback&quot;&gt;Writeback&lt;&#x2F;h1&gt;
&lt;p&gt;This is arguably the simplest pipeline stage, as all it does is write whatever needs to be written into
whatever register needs to be changed, given that the instruction does need to write something to a register.&lt;&#x2F;p&gt;
&lt;p&gt;Many instructions will compute something with the ALU during &lt;code&gt;AGEX&lt;&#x2F;code&gt; and then write that result into &lt;code&gt;rd&lt;&#x2F;code&gt;, whose
address is given by the instruction. Load instructions will use the retrieved data from &lt;code&gt;M&lt;&#x2F;code&gt;, and jump instructions
will store the return linkage into &lt;code&gt;rd&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;figure&gt;

	&lt;img class=&quot;
			
			
			
			
                        
		&quot;
		
		src=&quot;WB.png&quot; &#x2F;&gt;
	


&lt;figcaption&gt;Writeback stage&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;h1 id=&quot;putting-it-all-together&quot;&gt;Putting It All Together&lt;&#x2F;h1&gt;
&lt;p&gt;Now that we have our individual stages, it is time to connect them all!
We&#x27;re now halfway done with the CPU. All that&#x27;s left now is determining control signals and
creating the control unit. After that, we need to consider hazards and then test the design
by hand-tracing all the RV32I instructions as a final verification step before we begin the
implementation for an FPGA.&lt;&#x2F;p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;samienr.com&#x2F;blog&#x2F;designing-a-cpu-03&#x2F;datapath.png#full-bleed&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;figcaption&gt;Our (mostly) complete pipeline datapath&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Designing a CPU From Scratch, Part 2: Fundamental Components</title>
        <published>2025-12-19T00:00:00+00:00</published>
        <updated>2025-12-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Samien Rahman
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samienr.com/blog/designing-a-cpu-02/"/>
        <id>https://samienr.com/blog/designing-a-cpu-02/</id>
        
        <content type="html" xml:base="https://samienr.com/blog/designing-a-cpu-02/">&lt;h1 id=&quot;arithmetic-logic-unit-alu&quot;&gt;Arithmetic Logic Unit (ALU)&lt;&#x2F;h1&gt;
&lt;p&gt;After skimming through the RV32I instruction set, I figured I could start with
the arithmetic logic unit (ALU). The ALU is where most actual computations happen.
Its composition depends on what operations it needs to perform. For RV32I,
these are the operations I will need to implement for a functional ALU:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Instruction&lt;&#x2F;th&gt;&lt;th&gt;ALU Unit Needed&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;add&lt;&#x2F;code&gt;, &lt;code&gt;addi&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Adder&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;sub&lt;&#x2F;code&gt;, &lt;code&gt;slt&lt;&#x2F;code&gt;, &lt;code&gt;sltu&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Subtractor&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;slli&lt;&#x2F;code&gt;, &lt;code&gt;srli&lt;&#x2F;code&gt;, &lt;code&gt;srai&lt;&#x2F;code&gt;, &lt;code&gt;sll&lt;&#x2F;code&gt;, &lt;code&gt;sra&lt;&#x2F;code&gt;, &lt;code&gt;srl&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Shifter&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;and&lt;&#x2F;code&gt;, &lt;code&gt;or&lt;&#x2F;code&gt;, &lt;code&gt;xor&lt;&#x2F;code&gt;, &lt;code&gt;andi&lt;&#x2F;code&gt;, &lt;code&gt;ori&lt;&#x2F;code&gt;, &lt;code&gt;xori&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Primitive logic gates&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Our design will simply have circuitry to compute all these operations and
then multiplex out whatever an &lt;code&gt;ALU_Op&lt;&#x2F;code&gt; control signal requests.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m aware that there are some other instructions that do math, such as
&lt;code&gt;auipc&lt;&#x2F;code&gt; and &lt;code&gt;lui&lt;&#x2F;code&gt;. These operations will use their own dedicated
hardware outside of the ALU.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;condition-codes-flags&quot;&gt;Condition Codes&#x2F;Flags&lt;&#x2F;h2&gt;
&lt;p&gt;In addition to the operations, our machine also needs to generate condition
flags. RV32I doesn&#x27;t really define how we will handle whether branches are
taken or not, so how we approach this is up to us. The simplest approach
I found was only checking for three conditions:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Is our result zero?&lt;&#x2F;li&gt;
&lt;li&gt;Is A &amp;lt; B? (unsigned)&lt;&#x2F;li&gt;
&lt;li&gt;Is A &amp;lt; B? (signed)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;We can easily use the results of the subtractor for these signals. Every type of branch instruction we will need to consider can be resolved using these three conditions.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Instruction&lt;&#x2F;th&gt;&lt;th&gt;Logical Condition&lt;&#x2F;th&gt;&lt;th&gt;ALU Signal&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;beq&lt;&#x2F;td&gt;&lt;td&gt;A == B&lt;&#x2F;td&gt;&lt;td&gt;Zero&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;bne&lt;&#x2F;td&gt;&lt;td&gt;A != B&lt;&#x2F;td&gt;&lt;td&gt;NOT Zero&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;bltu&lt;&#x2F;td&gt;&lt;td&gt;A &amp;lt; B (unsigned)&lt;&#x2F;td&gt;&lt;td&gt;A &amp;lt; B (unsigned)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;bgeu&lt;&#x2F;td&gt;&lt;td&gt;A &amp;gt;= B (unsigned)&lt;&#x2F;td&gt;&lt;td&gt;NOT A &amp;lt; B (unsigned)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;blt&lt;&#x2F;td&gt;&lt;td&gt;A &amp;lt; B (signed)&lt;&#x2F;td&gt;&lt;td&gt;A &amp;lt; B (signed)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;bge&lt;&#x2F;td&gt;&lt;td&gt;A &amp;gt;= B (signed)&lt;&#x2F;td&gt;&lt;td&gt;NOT A &amp;lt; B (signed)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The &lt;code&gt;zero&lt;&#x2F;code&gt; condition will simply check if A and B are equal to each other.&lt;br &#x2F;&gt;
The less than (unsigned) condition &lt;code&gt;ltU&lt;&#x2F;code&gt; will be computed by subtracting
&lt;code&gt;A - B&lt;&#x2F;code&gt; and taking the complement of the subtractor&#x27;s borrow bit.&lt;br &#x2F;&gt;
The less than (signed) condition &lt;code&gt;lt&lt;&#x2F;code&gt; will use the same subtractor and
result. Its value will come from the &lt;code&gt;XOR&lt;&#x2F;code&gt; of the subtractor&#x27;s borrow
bit and another signal that indicates whether or not the subtractor had overflow.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;alu-code&quot;&gt;ALU Code&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;verilog&quot; style=&quot;background-color:#212733;color:#ccc9c2;&quot; class=&quot;language-verilog &quot;&gt;&lt;code class=&quot;language-verilog&quot; data-lang=&quot;verilog&quot;&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;module &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;ALU&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;A&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;B&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] ALU_Op,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;output &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;reg&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] Result,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    output&lt;&#x2F;span&gt;&lt;span&gt; zero, lt, ltU
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;wire&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] sub_full &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= {&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;1&amp;#39;b0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;A&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;} - {&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;1&amp;#39;b0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;B&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;wire&lt;&#x2F;span&gt;&lt;span&gt; sub_overflow &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;A&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;^ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;B&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span&gt;]) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; (sub_full[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;^ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;A&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span&gt;]);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;assign&lt;&#x2F;span&gt;&lt;span&gt; zero &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;A &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;B&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;assign&lt;&#x2F;span&gt;&lt;span&gt; lt  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; sub_full[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;^&lt;&#x2F;span&gt;&lt;span&gt; sub_overflow;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;assign&lt;&#x2F;span&gt;&lt;span&gt; ltU &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= ~&lt;&#x2F;span&gt;&lt;span&gt;sub_full[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;always &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;begin
&lt;&#x2F;span&gt;&lt;span&gt;Result &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;32&amp;#39;b0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;case&lt;&#x2F;span&gt;&lt;span&gt; (ALU_Op)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;`ALU_ADD&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;       Result &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;A &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;B&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;`ALU_SUB&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;       Result &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; sub_full[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;`ALU_SHF_L&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;     Result &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;A &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;B&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;`ALU_SHF_R_L&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;   Result &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;A &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;&amp;gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;B&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;`ALU_SHF_R_A&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;   Result &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f28779;&quot;&gt;$signed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;A&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;B&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;`ALU_AND&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;       Result &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;A &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;B&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;`ALU_OR&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;        Result &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;A &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;B&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;`ALU_XOR&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;       Result &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;A &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;^ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;B&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;`ALU_PASSB&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;     Result &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;B&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;`ALU_SLT&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;       Result &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= {{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;1&amp;#39;b0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;}}&lt;&#x2F;span&gt;&lt;span&gt;, lt&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;`ALU_SLTU&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;      Result &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= {{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;1&amp;#39;b0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;}}&lt;&#x2F;span&gt;&lt;span&gt;, ltU&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;default&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;        Result &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;A&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;endcase
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;endmodule
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;register-file&quot;&gt;Register File&lt;&#x2F;h1&gt;
&lt;p&gt;This is one of the most trivial yet most important components to make.
Since we won&#x27;t be doing anything superscalar or out-of-order just yet,
we can get away with writing a very simple register file with just two
read ports and one write port. Our ISA tells us that we have 32 registers
with 32 bits each. Since reading doesn&#x27;t change state, we can make that
part combinational and save some time. However, since writing does change
state, it must be synchronized, so changes will only be made on rising
clock edges. Other than that, the only thing we need to keep in mind is
that the x0 register (address 0b00000) is always 0, and writing to it
makes no changes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;EDIT:&lt;&#x2F;strong&gt; Looks like I missed something here. Since this machine is going
to be pipelined, we need to account for the case where one register is being
written by one instruction, but is simultaneously being read by a future
instruction in an earlier phase of the pipeline. In this case, the value
that is being written must be forwarded to the next instruction, &lt;em&gt;not&lt;&#x2F;em&gt; the
value that was there before. To fix this, all we need is the ability to
directly output what is being written if the destination register happens
to be one of the source registers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;register-file-code&quot;&gt;Register File Code&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;verilog&quot; style=&quot;background-color:#212733;color:#ccc9c2;&quot; class=&quot;language-verilog &quot;&gt;&lt;code class=&quot;language-verilog&quot; data-lang=&quot;verilog&quot;&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;module &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;RegFile&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; clk,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] rs1,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] rs2,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; we,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] wr_addr,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] wr_data,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    output&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] rd1,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    output&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] rd2
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;    reg&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] registers[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;always &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;posedge&lt;&#x2F;span&gt;&lt;span&gt; clk)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (we &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; wr_addr &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;!= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;5&amp;#39;b0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;            registers[wr_addr] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; wr_data;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;assign&lt;&#x2F;span&gt;&lt;span&gt; rd1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; (rs1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;? &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;32&amp;#39;b0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6773;&quot;&gt;&#x2F;&#x2F; read x0
&lt;&#x2F;span&gt;&lt;span&gt;                 (rs1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; wr_addr &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; we) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt; wr_data &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6773;&quot;&gt;&#x2F;&#x2F; bypass
&lt;&#x2F;span&gt;&lt;span&gt;                 registers[rs1]; &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6773;&quot;&gt;&#x2F;&#x2F; normal read
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;assign&lt;&#x2F;span&gt;&lt;span&gt; rd2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; (rs2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;? &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;32&amp;#39;b0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                 (rs2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; wr_addr &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; we) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt; wr_data &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                 registers[rs2];
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;endmodule
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;program-counter-pc&quot;&gt;Program Counter (PC)&lt;&#x2F;h1&gt;
&lt;p&gt;Even more trivial than the register file is the PC. The PC is a simple 32-bit register
that can be updated every cycle. In real hardware, this would be driven by some reset
logic or a boot ROM.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pc-code&quot;&gt;PC Code&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;verilog&quot; style=&quot;background-color:#212733;color:#ccc9c2;&quot; class=&quot;language-verilog &quot;&gt;&lt;code class=&quot;language-verilog&quot; data-lang=&quot;verilog&quot;&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;module &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;PC&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; clk,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; we,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] in,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    output&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] out
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;    reg&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] counter;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;initial&lt;&#x2F;span&gt;&lt;span&gt; counter &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;32&amp;#39;h8000_0000&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;assign&lt;&#x2F;span&gt;&lt;span&gt; out &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; counter;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;always &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;posedge&lt;&#x2F;span&gt;&lt;span&gt; clk)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (we) counter &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; in;
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;endmodule
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;memory&quot;&gt;Memory&lt;&#x2F;h1&gt;
&lt;p&gt;Even though RISC-V architecturally has instruction and data memory unified,
I&#x27;m going to keep instructions and data separate in hardware as it makes
pipelining much less of a headache. They&#x27;re usually cached separately in
most machines anyways.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;instructions&quot;&gt;Instructions&lt;&#x2F;h2&gt;
&lt;p&gt;We will make the instruction memory behave like a synchronous ROM.
We&#x27;ll also ensure that it is only word addressable.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;verilog&quot; style=&quot;background-color:#212733;color:#ccc9c2;&quot; class=&quot;language-verilog &quot;&gt;&lt;code class=&quot;language-verilog&quot; data-lang=&quot;verilog&quot;&gt;&lt;span style=&quot;font-style:italic;color:#5c6773;&quot;&gt;&#x2F;&#x2F; TODO: Add simulated delay
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;module &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;InstructionMemory&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; clk,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] addr,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;output &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;reg&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] instruction
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;    reg&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] mem [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;1023&lt;&#x2F;span&gt;&lt;span&gt;]; &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6773;&quot;&gt;&#x2F;&#x2F; 4KB Instruction Memory (1024 words)
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6773;&quot;&gt;&#x2F;&#x2F; TODO: load test program    
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6773;&quot;&gt;&#x2F;&#x2F;    initial $readmemh(&amp;quot;program.hex&amp;quot;, mem);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;always &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;posedge&lt;&#x2F;span&gt;&lt;span&gt; clk)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6773;&quot;&gt;&#x2F;&#x2F; chop off last two bits to ensure word aligned
&lt;&#x2F;span&gt;&lt;span&gt;        instruction &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; mem[addr[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]];
&lt;&#x2F;span&gt;&lt;span&gt;        
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;endmodule
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;data&quot;&gt;Data&lt;&#x2F;h2&gt;
&lt;p&gt;Data memory is a little more complicated as we need to be able to operate on
bytes, halfwords, and words for stores. I&#x27;m just going to model this internally
as an array of 8-bit registers. The input and output will be in terms of words,
and a &lt;code&gt;byte_en&lt;&#x2F;code&gt; signal will determine how many bytes are actually going into memory.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;verilog&quot; style=&quot;background-color:#212733;color:#ccc9c2;&quot; class=&quot;language-verilog &quot;&gt;&lt;code class=&quot;language-verilog&quot; data-lang=&quot;verilog&quot;&gt;&lt;span style=&quot;font-style:italic;color:#5c6773;&quot;&gt;&#x2F;&#x2F; word aligned accesses only from core&amp;#39;s POV, internally byte addresable
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;module &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;DMem&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; clk,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; we,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] byte_en,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] addr,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    input&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] din,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;output &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;reg&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] dout,
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5ccfe6;&quot;&gt;    output&lt;&#x2F;span&gt;&lt;span&gt; ready
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;assign&lt;&#x2F;span&gt;&lt;span&gt; ready &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;1&amp;#39;b1&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6773;&quot;&gt;&#x2F;&#x2F; TODO: simulate delay
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;    reg&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] mem[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;4095&lt;&#x2F;span&gt;&lt;span&gt;]; &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5c6773;&quot;&gt;&#x2F;&#x2F; 4KB addressable
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;always &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;@&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;posedge&lt;&#x2F;span&gt;&lt;span&gt; clk) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;begin
&lt;&#x2F;span&gt;&lt;span&gt;        dout &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;&amp;lt;= {&lt;&#x2F;span&gt;&lt;span&gt;mem[addr[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;], 
&lt;&#x2F;span&gt;&lt;span&gt;                 mem[addr[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;], 
&lt;&#x2F;span&gt;&lt;span&gt;                 mem[addr[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;], 
&lt;&#x2F;span&gt;&lt;span&gt;                 mem[addr[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (we) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;begin
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (byte_en[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]) mem[addr[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; din[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (byte_en[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]) mem[addr[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; din[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (byte_en[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]) mem[addr[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; din[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (byte_en[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;]) mem[addr[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; din[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29e74;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffa759;&quot;&gt;endmodule
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;what-s-next&quot;&gt;What&#x27;s Next?&lt;&#x2F;h1&gt;
&lt;p&gt;Now we have the most basic components, we are ready to think about how we
will decode instructions and wire the datapath. That will involve creating
the control signals, logic relating to control signals, smaller intermediate
components depending on what instructions need, and the pipeline registers.
After we do that, all that should be left is hazard control, handling
branches, and testing.&lt;&#x2F;p&gt;
&lt;p&gt;For now, feel free to take a look at the
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;samienr&#x2F;risc-v-toy&quot;&gt;source HDL code I have so far on my GitHub.&lt;&#x2F;a&gt;
Until then, take care!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Designing a CPU From Scratch, Part 1: ISA</title>
        <published>2025-10-26T00:00:00+00:00</published>
        <updated>2025-10-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Samien Rahman
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samienr.com/blog/designing-a-cpu-01/"/>
        <id>https://samienr.com/blog/designing-a-cpu-01/</id>
        
        <content type="html" xml:base="https://samienr.com/blog/designing-a-cpu-01/">&lt;p&gt;I&#x27;ve been wanting to practice my understanding of computer architecture ever since I completed &lt;a href=&quot;https:&#x2F;&#x2F;users.ece.utexas.edu&#x2F;~patt&#x2F;24f.460n&#x2F;&quot;&gt;this course&lt;&#x2F;a&gt; during my studies. However, I didn&#x27;t know Verilog at the time, so the most I could do was a cycle-accurate pipelined &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;samienr&#x2F;ECE460N&#x2F;tree&#x2F;main&#x2F;lab6&#x2F;submission&quot;&gt;simulator&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The goal is to take this project to the next level: &lt;strong&gt;I&#x27;m going to make a synthesizable pipelined RISC-V core in RTL.&lt;&#x2F;strong&gt; The goal is simple: create a pipelined, in-order processor that can execute RV32I instructions.&lt;&#x2F;p&gt;
&lt;p&gt;After I get some basic functionality, I will try to implement support for interrupts&#x2F;exceptions. Then I&#x27;ll explore caches, branch prediction, and out-of-order execution.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;instruction-set-architecture&quot;&gt;Instruction Set Architecture&lt;&#x2F;h1&gt;
&lt;p&gt;The instruction set architecture (ISA) is the contract between hardware and software, meaning it defines how instructions are encoded, what registers exist, and what operations a CPU can perform. It is &lt;strong&gt;not&lt;&#x2F;strong&gt; the implementation details. In other words, it defines &lt;em&gt;what&lt;&#x2F;em&gt; the CPU can do, but doesn&#x27;t dictate &lt;em&gt;how.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Choosing the ISA is a &lt;em&gt;very significant&lt;&#x2F;em&gt; decision as it affects the CPUs fundamental design, and everything that builds on it. This includes instruction encoding, register file, and memory.&lt;&#x2F;p&gt;
&lt;p&gt;Since the primary purpose of this project is the learning experience, I figured using the RV32I instruction set is a no-brainer. The abundance of resources due to RISC-V&#x27;s open-source nature makes it a natural choice for such a learning exercise.&lt;&#x2F;p&gt;
&lt;p&gt;With that in mind, I can start designing the individual logical components of the processor. I don&#x27;t have the entire thing planned out yet, but I&#x27;m going to begin with the following components, then continue with whatever makes the most sense:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;ALU&lt;&#x2F;li&gt;
&lt;li&gt;Register file&lt;&#x2F;li&gt;
&lt;li&gt;Decoder + control signals&lt;&#x2F;li&gt;
&lt;li&gt;We&#x27;ll figure it out as we go&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Once I get everything working, I&#x27;ll try to get this running on an FPGA.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m optimistic I can get this done within a few months, but Murphy&#x27;s Law &lt;em&gt;is&lt;&#x2F;em&gt; very much a thing.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How I Designed My First Custom Keyboard</title>
        <published>2024-06-14T00:00:00+00:00</published>
        <updated>2024-06-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Samien Rahman
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samienr.com/blog/keyboard/"/>
        <id>https://samienr.com/blog/keyboard/</id>
        
        <content type="html" xml:base="https://samienr.com/blog/keyboard/">&lt;p&gt;I&#x27;ve been into custom mechanical keyboards for a while, but the absurdly high costs and long wait times for parts pushed me towards a different solution: designing and building a keyboard myself. As a college student, affordability and quick access are key, and the custom keyboard is just the opposite of that, so I decided to take on this project myself.&lt;&#x2F;p&gt;
&lt;p&gt;I figured if I were going to design the keyboard entirely myself, I might as well make it as &lt;em&gt;custom&lt;&#x2F;em&gt; as possible. I was going to design this keyboard something &lt;em&gt;just for myself&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;design&quot;&gt;Design&lt;&#x2F;h1&gt;
&lt;p&gt;Within a few weeks of &lt;a href=&quot;https:&#x2F;&#x2F;reddit.com&#x2F;r&#x2F;ErgoMechKeyboards&quot;&gt;snooping around online&lt;&#x2F;a&gt;, I discovered a whole world of bizarrely-shaped, split keyboards. I very quickly became inspired by the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kata0510&#x2F;Lily58&quot;&gt;Lily58&lt;&#x2F;a&gt; and the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;foostan&#x2F;crkbd&quot;&gt;Corne&lt;&#x2F;a&gt;. I learned that the  motivation behind these strange layouts came from two goals that I had myself:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Reducing finger movement&lt;&#x2F;li&gt;
&lt;li&gt;Enhanced typing comfort&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Both of these goals are achieved by two design choices:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Less keys = less places for my fingers to go&lt;&#x2F;li&gt;
&lt;li&gt;Key placement matching the natural positioning of fingers— meaning a split layout&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;To start, I mapped out a rough layout by tracing my finger movements using a painting app on an iPad.

	&lt;img class=&quot;
			
			
			
			no-hover
                        
		&quot;
		alt=&quot;Traced finger positions&quot;
		src=&quot;finger_paint.png&quot; &#x2F;&gt;
	

&lt;&#x2F;p&gt;
&lt;figcaption&gt;Super basic, I know.&lt;&#x2F;figcaption&gt;
&lt;p&gt;That gave a basic idea of the where each finger naturally goes as I extend them.&lt;&#x2F;p&gt;
&lt;p&gt;As for hardware, I chose:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Seeed Studio XIAO nRF52840&lt;&#x2F;strong&gt; microcontroller for its Bluetooth Low Energy capability, affordable price, and ARM architecture.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Kalih Choc Red switches&lt;&#x2F;strong&gt; for their low profile and because I like linear switches&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;h1 id=&quot;ergogen&quot;&gt;Ergogen&lt;&#x2F;h1&gt;
&lt;p&gt;I needed a tool to design the layout and found &lt;a href=&quot;https:&#x2F;&#x2F;ergogen.cache.works&#x2F;&quot;&gt;Ergogen&lt;&#x2F;a&gt;. , which uses a simple YAML format to create layouts. Thanks to &lt;a href=&quot;https:&#x2F;&#x2F;flatfootfox.com&#x2F;ergogen-introduction&#x2F;&quot;&gt;a helpful blog series by FlatFootFox&lt;&#x2F;a&gt;, I defined a 3x6 grid for keys on each hand, matching the finger positions I had determined on the iPad. The flexibility of YAML allowed me to easily tweak the layout until it felt and looked right. Here&#x27;s a snippet of my Ergogen config:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yaml&quot; style=&quot;background-color:#212733;color:#ccc9c2;&quot; class=&quot;language-yaml &quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;columns&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;outer&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;splay&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;10
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;pinky&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;stagger&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;3
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;ring&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;stagger&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;8
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;splay&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;-4&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;spread&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;1.035kx
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;middle&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;stagger&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;.25*ky
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;splay&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;-5
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;spread&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;1.04kx
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;index&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;stagger&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;-.65*ky
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;splay&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;-1
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;inner&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;stagger&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;-.5*ky
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;rows&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;bottom&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;home&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;top&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;thumb&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;padding&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;ky
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;spread&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;kx
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;anchor&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bae67e;&quot;&gt;matrix_index_bottom
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;shift&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;-28&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;columns&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;left&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;shift&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;-1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;splay&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;-15
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;middle&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;splay&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;-7&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;5
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;right&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;splay&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;-15
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;shift&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffcc66;&quot;&gt;-2&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;rows&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#73d0ff;&quot;&gt;cluster&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ccc9c2cc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I used &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ceoloide&#x2F;ergogen-footprints&#x2F;tree&#x2F;main&quot;&gt;Ceoloide&#x27;s&lt;&#x2F;a&gt; footprint for the switch footprints, which are reversible, meaning that both halves of the board can use the same PCB design.&lt;&#x2F;p&gt;

	&lt;img class=&quot;
			
			
			
			no-hover
                        
		&quot;
		alt=&quot;Preview of layout in ergogen online tool&quot;
		src=&quot;ergogen_preview.png&quot; &#x2F;&gt;
	

&lt;figcaption&gt;Preview of layout generated in Ergogen&lt;&#x2F;figcaption&gt;
&lt;hr &#x2F;&gt;
&lt;h1 id=&quot;pcb-design&quot;&gt;PCB Design&lt;&#x2F;h1&gt;
&lt;p&gt;Ergogen generated a KiCad file with the board outline and switch footprints. I had to create and route the traces. Additionally, the footprint I used for the nRF52840 didn&#x27;t account for its battery pads, so I had to modify the footprint by adding a small cutout to route battery wires through. I haven&#x27;t messed around with PCBs before this besides some basic designs from school, so that was a nice learning experience. The supportive community on the &lt;a href=&quot;https:&#x2F;&#x2F;discord.gg&#x2F;kk4rXYkp4H&quot;&gt;Absolem Club Discord server&lt;&#x2F;a&gt; helped me through the process.&lt;&#x2F;p&gt;

	&lt;img class=&quot;
			
			
			
			no-hover
                        
		&quot;
		
		src=&quot;KiCad_before.png&quot; &#x2F;&gt;
	

&lt;figcaption&gt;The PCB Ergogen generated&lt;&#x2F;figcaption&gt;

	&lt;img class=&quot;
			
			
			
			no-hover
                        
		&quot;
		
		src=&quot;KiCad_after.png&quot; &#x2F;&gt;
	

&lt;figcaption&gt;After adding traces and adjusting the microcontroller footprint&lt;&#x2F;figcaption&gt;
&lt;p&gt;Once all the electronics were in place, I decided to add some decorative patterns to the pcb, as I decided not to use a plate on this keyboard.

	&lt;img class=&quot;
			
			
			
			no-hover
                        
		&quot;
		
		src=&quot;final_pcb.png&quot; &#x2F;&gt;
	


And with that, the PCB design was pretty much done. All that was left was ordering everything and putting it all together.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;assembly-and-firmware&quot;&gt;Assembly and Firmware&lt;&#x2F;h1&gt;
&lt;p&gt;I ordered my PCB from &lt;a href=&quot;https:&#x2F;&#x2F;jlcpcb.com&#x2F;&quot;&gt;JLCPCB&lt;&#x2F;a&gt; in black and white for about 20 USD, the microcontroller from &lt;a href=&quot;https:&#x2F;&#x2F;www.seeedstudio.com&#x2F;&quot;&gt;SeeedStudio&lt;&#x2F;a&gt;, and the other components from &lt;a href=&quot;https:&#x2F;&#x2F;typeractive.xyz&#x2F;&quot;&gt;Typeractive&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I used my university&#x27;s makerspace for soldering, learning about reflow soldering for smaller components.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;keymap&quot;&gt;Keymap&lt;&#x2F;h2&gt;
&lt;p&gt;First, I defined the keymap. I opted for Colemak-DH, as it was designed to be a more ergonomic layout that also allows for faster typing speeds. The other layers were designed by seeing various designs online and then just iterating.&lt;&#x2F;p&gt;
&lt;p&gt;I had initially set out to write the keymap directly to the ZMK keymap file, but I quickly found &lt;a href=&quot;https:&#x2F;&#x2F;nickcoutsos.github.io&#x2F;keymap-editor&#x2F;&quot;&gt;Keymap Editor&lt;&#x2F;a&gt;, an online tool that can connect to a ZMK repository on GitHub and manage the keymaps with a very easy to use GUI. I used the tool to create these keymaps:&lt;&#x2F;p&gt;

	&lt;img class=&quot;
			
			
			
			no-hover
                        
		&quot;
		
		src=&quot;default_layer.png&quot; &#x2F;&gt;
	

&lt;figcaption&gt;Default layer&lt;&#x2F;figcaption&gt;

	&lt;img class=&quot;
			
			
			
			no-hover
                        
		&quot;
		
		src=&quot;symbol_layer.png&quot; &#x2F;&gt;
	

&lt;figcaption&gt;Symbol layer&lt;&#x2F;figcaption&gt;

	&lt;img class=&quot;
			
			
			
			no-hover
                        
		&quot;
		
		src=&quot;number_layer.png&quot; &#x2F;&gt;
	

&lt;figcaption&gt;Number layer&lt;&#x2F;figcaption&gt;

	&lt;img class=&quot;
			
			
			
			no-hover
                        
		&quot;
		
		src=&quot;tri_layer.png&quot; &#x2F;&gt;
	

&lt;figcaption&gt;Function layer&lt;&#x2F;figcaption&gt;

	&lt;img class=&quot;
			
			
			
			no-hover
                        
		&quot;
		
		src=&quot;gaming_layer.png&quot; &#x2F;&gt;
	

&lt;figcaption&gt;Gaming layer&lt;&#x2F;figcaption&gt;
&lt;p&gt;I also decided to make another layer for gaming to keep the WASD layout, but I haven’t been able to test how effective this is.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;firmware&quot;&gt;Firmware&lt;&#x2F;h2&gt;
&lt;p&gt;I then opted for the ZMK Firmware, namely because QMK does not support wireless boards due to some licensing issues with Bluetooth, and because I do intend on learning Zephyr eventually, which ZMK is based on.&lt;&#x2F;p&gt;
&lt;p&gt;I began by mapping the pins on the microcontroller to the corresponding columns and rows of the keyboard matrix. I probably should’ve planned these before designing the PCB, but I chose these pins retroactively, as the PCB traces were already routed.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Pin Number&lt;&#x2F;th&gt;&lt;th&gt;Digital&lt;&#x2F;th&gt;&lt;th&gt;Matrix mapping&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;P0.02&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;Outer Column&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;P0.03&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;Pinky Column&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;P0.28&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;Middle Column + outerthumb&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;P0.29&lt;&#x2F;td&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;Index Column + middlethumb&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;P0.04&lt;&#x2F;td&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;Inner Column + innerthumb&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;P1.12&lt;&#x2F;td&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;Upper Row&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;P1.13&lt;&#x2F;td&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;Middle Row&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;P1.14&lt;&#x2F;td&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;Lower Row&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;P1.15&lt;&#x2F;td&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;Thumb Row&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;creating-the-shield&quot;&gt;Creating the shield&lt;&#x2F;h3&gt;
&lt;p&gt;Because this keyboard was completely original, there wasn’t a pre-existing shield, so I had to make my own. That wasn’t so bad. The &lt;a href=&quot;https:&#x2F;&#x2F;zmk.dev&#x2F;docs&#x2F;development&#x2F;new-shield&quot;&gt;ZMK documentation&lt;&#x2F;a&gt; is very well written and easy to follow.&lt;&#x2F;p&gt;
&lt;p&gt;All that was left was to compile and flash the firmware! &lt;small&gt;Not Really&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;trouble-in-paradise&quot;&gt;Trouble in Paradise&lt;&#x2F;h1&gt;
&lt;p&gt;Despite the careful planning and assembly, I ran into a significant issue: the left half of the keyboard worked perfectly and paired with my devices, but the right half was unresponsive.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;initial-diagnosis&quot;&gt;Initial Diagnosis&lt;&#x2F;h3&gt;
&lt;p&gt;I tried resetting the firmware, suspecting an issue with the pairing process. This fixed the issue in that the right half now connected, but it also led me to find another problem: most keys on the right half were unresponsive, and pressing the top key in each column caused all keys in that column to ghost.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;physical-troubleshooting&quot;&gt;Physical Troubleshooting&lt;&#x2F;h3&gt;
&lt;p&gt;I grabbed a multimeter to test each diode, as my soldering job for the right half was particularly ugly, but each diode was functioning correctly. Next, I tested each diode-switch pair, where I did find an inconsistency in voltages. I then tried flipping all the diodes, as perhaps the direction needed to be flipped because the board was flipped, but this yielded no change. It was time to take a look at the PCB.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pcb-analysis&quot;&gt;PCB Analysis&lt;&#x2F;h3&gt;
&lt;p&gt;I next decided to take a look at the PCB layout. This is where I found the culprit. I discovered that I had forgotten to route one of the pads on the backside (the front for the right side of the board). Fortunately, because the left and right halves of the board use the same PCB, I was able to simply resolder the microcontroller to the back side of the right half. I knew this would work because the left side worked flawlessly, and although the diode pads were on the other side, all the switch connections were through-holes, so the side on which they were installed would not matter. All that was left was to compensate with software by reversing the order of the pins. This finally worked.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h1&gt;
&lt;p&gt;This project was a bit challenging but very rewarding, providing me with a custom mechanical keyboard tailored to my preferences. It was also my first truly original electronics project, and it taught me a lot about PCB design and soldering, all through practical hands-on experience. This project also helped in refining my independent problem-solving skills, as I am used to having either documentation or peers to take help from. I hope this inspires others to try their hand at DIY keyboard building!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;open-source&quot;&gt;Open Source (?)&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve finally open sourced the keyboard design files on &lt;a class=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;samienr&#x2F;SOR-Hydrogen&quot;&gt;this Github repository.&lt;&#x2F;a&gt; I haven&#x27;t yet fixed the PCB routing mistake, though I do plan on getting to it eventually. It&#x27;s just not a high priority at the moment. Feel free to do whatever you want with the designs, this project was more for the learning experience.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;next-steps&quot;&gt;Next Steps&lt;&#x2F;h1&gt;
&lt;p&gt;I&#x27;m probably going to work on a case for the boards next. The goal as it stands now is to create a model for 3D printing just to protect the boards (and the surfaces I put them on), then to eventually design a case for either CNC milling or resin printing that holds the boards at the most comfortable angles for me.&lt;&#x2F;p&gt;

	&lt;img class=&quot;
			
			
			
			
                        
		&quot;
		
		src=&quot;keyboard.jpg&quot; &#x2F;&gt;
	

&lt;figcaption&gt;The completed product&lt;&#x2F;figcaption&gt;
</content>
        
    </entry>
</feed>
