## Beginning Logic Design – Part 6

Hello and welcome to Part 6 of my Beginning Logic Design series. In the last post I laid out the start of an ALU design. In this round I will be completing the ADD operation including support for the various status flags and build some tests to validate it.

As a quick reference, here’s the description I laid out in the previous post.

The ALU I’ll be designing in this post will be influenced by the classic 6502 processor that’s at the heart of the NES, Apple II and many other early computer systems. This ALU with support 12 operations:

• Arithmetic Operations
• Subtract with Carry
• Increment
• Decrement
• Logic Operations
• AND
• OR
• XOR
• NOT/Negate (not in 6502, but I want my ALU to have it!)
• Shifting Operations
• Arithmetic Shift Left
• Logical Shift Right
• Rotate Left
• Rotate Right

This ALU will also have a few status signals, on the input side it will just have `carry in`, on the output side we’ll have `carry out`, `zero`, `sign` and `overflow`. I’ll dive a bit more into each of these operations and how the interact with status signals as we implement them.

To complete out the `ADD` operation as specified, it needs to factor in a `carry` input signal and output the other status signals as well.

Following the general structure of what the 6502 architecture does, I’ll reference this 6502 opcode document for which flags are modified by which operations, and this 6502 processor document as a reference to the meanings for each flag. I also found this article on the overflow flag  helpful to wrap my head around its meaning and purpose.

To understand what all these flags mean, some familiarity with representing signed numbers and two’s complement is needed to understand the semantics of these flags, and it also helps to understand how subtraction is implemented in digital machines. I suggest this Computerphile video for an overview on unsigned, signed magnitude and twos complement binary representation.

Here’s how each flag should be responding in our addition circuit:

• `zero` should be 1 if the result of the addition is zero
• `sign` should be 1 if the the result could be interpreted as a negative number (in signed addition)
• `carry` should be 1 if the addition results in an unsigned number that is wider than 8 bits
• `overflow` should be 1 if the addition resulted in a number that is outside of the range supported by an 8 bit signed number: `sum < -128` or `sum > 127`

To get started on this, the first thing I’ll do is add the input and output ports for these signals to my ALU. I’ll also use `assign` to set them all to `0` for now.

```module alu (
input logic clock,
input opcode operation,
input logic [7:0] a,
input logic [7:0] b,
input logic carry_in,
output logic [7:0] y,
output logic zero,
output logic sign,
output logic carry_out,
output logic overflow
);

assign zero = 0,
sign = 0,
carry_out = 0,
overflow = 0;```

Then I’ll also update my `top` module to include variables to route these in and out of the `alu`.

```module top ();
logic clock;
opcode operation;
logic [7:0] a;
logic [7:0] b;
logic carry_in;
logic [7:0] y;
logic zero;
logic sign;
logic carry_out;
logic overflow;

alu myALU (
clock,
operation,
a,
b,
carry_in,
y,
zero,
sign,
carry_out,
overflow
);

...```

I’ll also add `carry_in = 0;` in my `initial` block within `top` to set that signal to `0` at the start.

# Test Driven Development

Many software developers are supporters of test driven development, but in the hardware world the concept of writing your tests before your implementation this is the norm.

It can be incredibly easy to add a flaw to our designs. The `ADD` operation here supports signed and unsigned addition. Interestingly enough the only difference between signed and unsigned addition is what the number means to you, the potential user of the ALU. If we do the operation `80 + 80`, and intended that be unsigned addition result would be `160`, but we intended signed addition it would erroneously be `-96` because the number went beyond the maximum number a signed 8-bit number can support (127).

If we look at this in hexadecimal it is `0x50 + 0x50 = 0xA0` in either case, but the hexadecimal number `0xA0` has a different value if looked at as a signed (`160`) or unsigned (`-96`) number. We use the the `carry_out` status flag to let us know when our addition exceeds what can be accurately represented in our unsigned integer range `[0, 255]`. Similarly, we use the `overflow` status flag to know when a signed addition goes beyond what can accurately be represented in our signed integer range `[-128, 127]`.

Implementing an adder that let’s us see all of this can be tricky, so let’s identify some of the special cases we need to be able to handle. The first round of tests I will write will use the table from this article on the 6502 overflow flag as a base.

I’ll now start writing some tests for my ALU. For this, I’ll use `assert` statements to check if the outputs are matching what I’d expect. Here’s the top module modified to include a test that validates a case where both `overflow` and `carry` should be set.

```initial begin
clock = 0;
// Test 208 + 144
a = 208;
b = 144;
carry_in = 0;
#2 assert(y == 96);
assert(zero == 0);
assert(sign == 0);
assert(carry_out == 1);
assert(overflow == 1);

#1 \$finish();

end```

I added `\$finish();` at the end to stop simulation there. Now I’ll fire off the simulator and see how it goes.

In the simulator window there’s no indication of an error, but in the Tcl Console at the bottom I can see some output that indicates some assertions failed.

```Error: Assertion violation
Time: 2 ns  Iteration: 0  Process: /top/Initial30_1  File: /home/kwilke/suchprogramming/my-alu/my-alu.srcs/sources_1/new/top.sv
Error: Assertion violation
Time: 2 ns  Iteration: 0  Process: /top/Initial30_1  File: /home/kwilke/suchprogramming/my-alu/my-alu.srcs/sources_1/new/top.sv
\$finish called at time : 3 ns : File "/home/kwilke/suchprogramming/my-alu/my-alu.srcs/sources_1/new/top.sv" Line 44```

The error message shows when the assertion failed, but no information is given as to why. To make the error more informational I can add an `else` statement followed by a `\$error()` call to have the simulator spit out a more descriptive error.

```#2 assert(y == 96) else \$error("Sum assertion failed.");
assert(zero == 0) else \$error("Zero assertion failed.");
assert(sign == 0) else \$error("Sign assertion failed.");
assert(carry_out == 1) else \$error("Carry assertion failed.");
assert(overflow == 1) else \$error("Overflow assertion failed.");```

Now when I run the simulation, I can more clearly see what has failed.

```Error: Carry assertion failed.
Time: 2 ns  Iteration: 0  Process: /top/Initial30_1  File: /home/kwilke/suchprogramming/my-alu/my-alu.srcs/sources_1/new/top.sv
Error: Overflow assertion failed.
Time: 2 ns  Iteration: 0  Process: /top/Initial30_1  File: /home/kwilke/suchprogramming/my-alu/my-alu.srcs/sources_1/new/top.sv
\$finish called at time : 3 ns : File "/home/kwilke/suchprogramming/my-alu/my-alu.srcs/sources_1/new/top.sv" Line 44```

# Implementing The Flags

Finding the `zero` flag is easy, we just need to see if our output is zero.

The `sign` flag is also easy, we just need to check if the most significant output bit is `1`.

The `carry` flag we can get by looking the result of our addition as 9 bits and looking at the most significant bit there.

The `overflow` flag is the trickiest, but the easiest way to get that is to take the `carry` of the 6th (counting from 0) bit’s sum and XOR that with the final `carry` output.

If I use the `y <= a + b;` syntax I have now, I can’t access any of the carry values. I need access to the last two carry values to set all of our flags properly. I also want to start factoring the `carry in` signal.

To break these needs up into easily accessed chunks, I’ll declare a few more internal variables.

```logic [7:0] add;

Next, I’ll define some combinational circuits with `assign`. I’ll first write an assignment that adds the lower bits and provides me my 6th carry bit.

```assign {add_carry_6, add_lower_bits} = a[6:0] + b[6:0] + carry_in,

The curly brackets here combine bits together. In the first statement the addition on the right results 8 bits of output and I use the brackets on the left to put the highest bit in `add_carry_6` and the remaining 7 bits in `add_lower_bits`. In this design I don’t use the lower bits but I set the size so I can easily get to that internal carry. I’ll use a similar assignment for the final carry and sum.

With easy access to all of the addition results I need, I can modify my `ADD` operation to use them to set my output and flags.

```ADD: begin
zero <= 1;
else
zero <= 0;
end```

Now I’ll need to remove my earlier `assign` block that was setting all my output flags to `0`, and I can run the simulation again!

It works! I’ll write a few more tests to validate some of the other operations but it should be good to go now! Here’s how my files have ended up.

`top.sv`

````timescale 1ns / 1ps

import ALU::*;

module top ();
logic clock;
opcode operation;
logic [7:0] a;
logic [7:0] b;
logic carry_in;
logic [7:0] y;
logic zero;
logic sign;
logic carry_out;
logic overflow;

alu myALU (
clock,
operation,
a,
b,
carry_in,
y,
zero,
sign,
carry_out,
overflow
);

initial begin
clock = 0;

// Test 208 + 144
a = 208;
b = 144;
carry_in = 0;
#2 assert(y == 96) else \$error("Sum assertion failed.");
assert(zero == 0) else \$error("Zero assertion failed.");
assert(sign == 0) else \$error("Sign assertion failed.");
assert(carry_out == 1) else \$error("Carry assertion failed.");
assert(overflow == 1) else \$error("Overflow assertion failed.");

// Test 208 + 48 (signed -48 + 48)
a = 208;
b = 48;
carry_in = 0;
#2 assert(y == 0) else \$error("Sum assertion failed.");
assert(zero == 1) else \$error("Zero assertion failed.");
assert(sign == 0) else \$error("Sign assertion failed.");
assert(carry_out == 1) else \$error("Carry assertion failed.");
assert(overflow == 0) else \$error("Overflow assertion failed.");

// Test 80 + 80
a = 80;
b = 80;
carry_in = 0;
#2 assert(y == 160) else \$error("Sum assertion failed.");
assert(zero == 0) else \$error("Zero assertion failed.");
assert(sign == 1) else \$error("Sign assertion failed.");
assert(carry_out == 0) else \$error("Carry assertion failed.");
assert(overflow == 1) else \$error("Overflow assertion failed.");

#1 \$finish();

end

always begin
#1 clock = ~clock;
end

endmodule```

`alu.sv`

````timescale 1ns / 1ps

package ALU;
typedef enum logic [3:0] {
SUBTRACT,
INCREMENT,
DECREMENT,
BIT_AND,
BIT_OR,
BIT_XOR,
BIT_NOT,
SHIFT_LEFT,
SHIFT_RIGHT,
ROTATE_LEFT,
ROTATE_RIGHT
} opcode;
endpackage

import ALU::*;

module alu (
input logic clock,
input opcode operation,
input logic [7:0] a,
input logic [7:0] b,
input logic carry_in,
output logic [7:0] y,
output logic zero,
output logic sign,
output logic carry_out,
output logic overflow
);

always_ff @ (posedge clock) begin
case (operation)
zero <= 1;
else
zero <= 0;
end
endcase
end

endmodule```

With our `ADD` operation fully functional that will finish this post. In the next post I will continue adding instructions and tests to this ALU to keep it moving closer to the model I outlined. If you have any feedback or questions please leave a comment. Keep tinkering!

Save

## Beginning Logic Design – Part 5

Hello and welcome to Part 5 of my Beginning Logic Design series. In this post I will begin building an 8-bit ALU (Arithmetic Logic Unit). Through building this ALU I will cover a few more topics on writing SystemVerilog and using Vivado to simulate the designs. As you learn more SystemVerilog, I suggest keeping this cheat sheet handy as a quick reference to notes regarding language syntax.

# ALU Model

An ALU is a very common component in various processing systems. The common ALU design takes an input opcode (operation code) to select one of various math or logic operations. Based on the operation selected, one or more inputs will be taken and the result of the operation will be output. ALUs may also read and write status signals based on the operation being performed.

The ALU I’ll be designing in this post will be influenced by the classic 6502 processor that’s at the heart of the NES, Apple II and many other early computer systems. This ALU with support 12 operations:

• Arithmetic Operations
• Subtract with Carry
• Increment
• Decrement
• Logic Operations
• AND
• OR
• XOR
• NOT/Negate (not in 6502, but I want my ALU to have it!)
• Shifting Operations
• Arithmetic Shift Left
• Logical Shift Right
• Rotate Left
• Rotate Right

This ALU will also have a few status signals, on the input side it will just have `carry in`, on the output side we’ll have `carry out`, `zero`, `sign` and `overflow`. I’ll dive a bit more into each of these operations and how the interact with status signals as we implement them.

# Building Modules

To get started I’ll fire up Vivado and make a new project that I’ll name `my-alu`. I’ll choose `RTL Project` for the Project Type and will leave `Do not specify sources at this time` unchecked to make a couple files right away.

In the Add Sources page I’ll use the `Create File` button to make two `SystemVerilog` files: `top` and `alu`. It’s easy to accidentally leave the file type on `Verilog` and the syntax for the older Verilog standard is a little different, so be sure to choose SystemVerilog.

For the Add Contraints page I will just hit next. As before for the Default Part page, I’ll select the `xc7a35ticsg324-1L` from the Search drop down to set as the default. After hitting finish I’ll hit OK to skip the module definition prompts.

I’ll then clean up my `top.sv` to look like this:

````timescale 1ns / 1ps

module top ();
endmodule```

And my `alu.sv` as:

````timescale 1ns / 1ps

module alu ();
endmodule```

My `top` module will help me test my ALU, and the `alu` module will eventually be my fully built ALU.

I want this ALU to work synchronously, so I will add an input clock. I’ll also add 2 8-bit inputs and 1 8-bit output to the `alu` module. To define an 8 bit `logic` variables, I’ll use the syntax `[n:0]` to give it a width of `n+1` bits, in this case `7` to give me `8` bits.

````timescale 1ns / 1ps

module alu (
input logic clock,
input logic [7:0] a,
input logic [7:0] b,
output logic [7:0] y
);
endmodule```

With those inputs and outputs defined, I’ll start to add the `alu` to the `top` module.

I’ll first define a few internal `logic` variables to use to connect to the inputs and outputs of the ALU. Then, to instantiate the ALU, I’ll reference the module name `alu` then name my instance `myALU` and in parenthesis, in the same order as defined in the `alu.sv` file,  I’ll provide my variables to use as inputs and outputs.

````timescale 1ns / 1ps

module top ();

logic clock;
logic [7:0] a;
logic [7:0] b;
logic [7:0] y;

alu myALU (
clock,
a,
b,
y
);
endmodule```

Now `myALU` exists within my `top` module, and I have hooked up some inputs and outputs to it.

# Setting the Clock

To set the clock, I am going to use some SystemVerilog syntax that is non-synthesizable. This means that actual hardware designs cannot be made from it, it exists in the language specifically for simulation and testing.

I’ll use an `initial` block to set all my input variables to 0 at the start of simulation.

```initial begin
clock = 0;
a = 0;
b = 0;
end```

Then I’ll add an `always` block that will repeatedly loop during simulation to invert my `clock` variable. The `#<t>` syntax adds a delay of `t` steps before the statement is executed.

```always begin
#1 clock = ~clock;
end```

In this case, I’ve used `#1` and with the `timescale` of `1ns / 1ps` this statement will be delayed by `1ns` in simulation.

Here’s how this leaves my `top.sv` file

````timescale 1ns / 1ps

module top ();
logic clock;
logic [7:0] a;
logic [7:0] b;
logic [7:0] y;

alu myALU (
clock,
a,
b,
y
);

initial begin
clock = 0;
a = 0;
b = 0;
end

always begin
#1 clock = ~clock;
end

endmodule```

I now want to `Run Simulation` to verify my clock is toggling on and off as I expect it to. Before I do that though, the simulator in Vivado by default runs for `1000 ns`, which is relatively long for this design. I’d like to reduce that to `20 ns` for now.

I’ll go to `Settings` in the `PROJECT MANAGER` portion of the `Flow Navigator` on the left side of Vivado. Then within `Project Settings` I’ll select `Simulation`, open the `Simulation` tab and set `xsim.simulate.runtime` to `20 ns`.

I’ll save my changes there and use `Run Simulation->Run Behavioral Simulation` to fire off the sim. After hitting the zoom fit icon I can validate it does flip every nanosecond.

# Enumerations in SystemVerilog

One of the advantages of using SystemVerilog instead of plain ol’ Verilog is being able to define enumerations. For this ALU, I need to create an input that can select one of the 12 operations I plan this ALU to support. I’ll use unique binary numbers to represent each operation in hardware and can use an enumeration to reference each operation in code by a more readable name.

I’ll also use `typedef` as you would in a language like C to use variables that should be set to a member within my enumeration. I’ll add `logic [3:0]` after `enum` to ensure the new type only uses 4 bits.

```typedef enum logic [3:0] {
SUBTRACT,
INCREMENT,
DECREMENT,
BIT_AND,
BIT_OR,
BIT_XOR,
BIT_NOT,
SHIFT_LEFT,
SHIFT_RIGHT,
ROTATE_LEFT,
ROTATE_RIGHT
} opcode;```

With this `enum` defined, I’ll add `input opcode operation` to my `alu` module’s list of ports.

```module alu (
input logic clock,
input opcode operation,
input logic [7:0] a,
input logic [7:0] b,
output logic [7:0] y
);

endmodule```

Now, within the `alu` module definition, I’ll use an `always_ff` block to implement synchronized behavior. I’ll use `@ (posedge clock)` to indicate that I want this block of behavior to occur on every `positive edge` (rise) of my `clock` signal.

Within that `always_ff` block, I will use `case` to vary the behavior based on what `operation` is set to, for now I’ll only add the logic for ADD.

```always_ff @ (posedge clock) begin
case (operation)
y <= a + b;
end
endcase
end```

In this situation, I use `<=` instead of `=` to store this within a register, which is like a D flip-flop with multiple bits, that will have its output wired to `y`. This keeps my output synchronized with my input.

I’m just about ready to test the addition operation. In order to reference the `opcode` type and enumeration within the `top` module, I need to `package` that up so I can use the `import` statement to refer to it.

I’ll wrap my typedef in `package ALU;``endpackage` to encapsulate it in a package named `ALU`. Then I will use `import ALU::*;` to import all of it for use in my `alu` module.

Here’s how this leaves my `afu.sv`

````timescale 1ns / 1ps

package ALU;
typedef enum logic [3:0] {
SUBTRACT,
INCREMENT,
DECREMENT,
BIT_AND,
BIT_OR,
BIT_XOR,
BIT_NOT,
SHIFT_LEFT,
SHIFT_RIGHT,
ROTATE_LEFT,
ROTATE_RIGHT
} opcode;
endpackage

import ALU::*;

module alu (
input logic clock,
input opcode operation,
input logic [7:0] a,
input logic [7:0] b,
output logic [7:0] y
);

always_ff @ (posedge clock) begin
case (operation)
y <= a + b;
end
endcase
end

endmodule```

For my `top` module; I’ll also add the `import` line, add an internal variable for `operation` and provide it to `myAFU`. I’ll set `operation` to `ADD` within my `initial` block and add a few more delayed operations to change `a` and `b` at different times within the simulation.

Let’s see how this works out.

I have an easier time verifying the math when the numbers are in decimal format. I can select multiple signals in the wave viewer by the first and holding shift and clicking the last, then right click and go to `Radix->Unsigned Decimal` to change the number format shown.

As you can verify in the simulation, on every rising clock edge the `y` output is updated to show the result of the addition of `a + b`!

With a lot of the foundation set for the ALU I’ll end the post here. In the next post I’ll finish implementing the ADD operation by adding status signal handling to help identify some special conditions that may result from the operation and how to setup better testing to validate the design.  As always, if you have any questions or feedback please leave a note in the comments. Keep tinkering!

Save

Save

Save

## Beginning Logic Design – Part 4

Hello and welcome to part 4 of my Beginning Logic Design series.

In the last couple posts we used Logicly to cover some introductory topics such as the basic logic gates, some combinational circuits for doing addition, and some sequential circuits we can use to store bits of data.

As we move on I’d like to cover increasingly more useful building blocks, but we’ll quickly outgrow what we can manage nicely in an educational logic simulator. While you can persevere and eventually build an entire CPU in Logicly, this is difficult and impractical.

Another reason to move beyond the basic logic simulator is I’d like to build some of these designs to see them operate in real life. While I have admiration for the folks that are building computers from scratch, I’d like an easier way. So today we’re going to change things up significantly!

Today we’re going to start exploring SystemVerilog and FPGAs!

# System What Now?

SystemVerilog is a hardware description language (HDL). An HDL is a language that lets you describe hardware with code, rather than designing with schematics.

This gives a ton of benefits. Primarily it let’s us focus more on what we’re trying to accomplish, rather than some of the nifty tricks we have to do with basic logic gates to implement designs. We give our HDL to programs that can convert our descriptions into actual designs.

SystemVerilog and similar languages play a large role in the design of modern integrated circuits. This is especially true in the design of ASICs and designs for FPGAs. Since building your own ASIC has a fairly high cost for a hobbyist, we’ll look at FPGAs and tools provided by the vendors that make them.

# Getting Started With FPGAs

There are two massive FPGA focused companies and a few other notable contenders. The biggest players are Altera (now owned by Intel) and Xilinx. Since the two big guys each have roughly 1/3 of the FPGA market it’s best to start with one of them since it’s easier to find boards and documentation.

I am more familiar with the Xilinx tools and I find their software, Vivado, is a bit less cluttered and makes simulation a bit easier, so I’ll be using that.

Using these tools can be daunting, so let’s jump right in and get something basic going before we get cold feet. Let’s open Vivado!

We’ll hit `Create Project` and step through the wizard. The first page of the wizard will introduce itself, then we’ll be prompted to name the project and select a directory for it to live in. I’ll call mine `hello-vivado` and store it in `/tmp` since I don’t intend to keep this project.

On the next page, I’ll select the project type, I’ll choose to RTL Project so we are ready for anything. I’ll skip the option to specify sources at this time.

The next page confused me a lot when I first tried to use Vivado with minimal FPGA experience, it asks you to pick a default FPGA out of their catalog of a bajillion parts. For simulated projects it doesn’t really matter, but I intend to buy the Arty A7 development board in the near future so I can run my designs on real hardware. I’ll choose the Artix-7 FPGA that board uses, part number `xc7a35ticsg324-1l`.

With that selected we can hit next and finish to get into our project.

There is a ton of functionality in Vivado, but we’ll ignore a lot of it for now. Let’s add a new file to our Sources. There is a plus sign we can use to add a new source file.

In the prompt that comes up, select `Add or create design sources`, and hit next. The screen will now present an interface for you to add or create files.

I’ll click `Create File` and select `SystemVerilog` as the file type. A common practice in FPGA design is to encapsulate your whole design as a module named `top`, and I will follow that convention.

I’ll hit OK followed by finish to close out of the add/create dialog. After you hit finish another prompt will come up to help you name the module and add I/O ports (similar to the connections that we had on components made in Logicly.) Just hit OK to accept its defaults and OK again to confirm. We’ll now have our `top` module in the `Design Sources` of our project.

We can double click on the `top.sv` file to open it in an editor. Vivado creates SystemVerilog files with a large comment for documenting some notes about the module, for brevity I’ll be deleting those comments from my files and I’ll indent things a bit differently.

````timescale 1ns / 1ps

module top ();
endmodule
```

This is our new empty module! The ``timescale` at the top tells the hardware simulator that we want to look at time measured in nanoseconds (a billionth of a second) and have values rounded to the nearest picosecond (a trillionth of a second).

The `module` keyword starts our description of a module named `top`. The parenthesis between `top` and `;` is where we can describe the signals coming in and out of our module. The `endmodule` keyword indicates the end of our module definition.

To start, let’s recreate our 1 bit half adder from the second post. That component took 2 inputs, `a` and `b` and returned a `sum` and a `carry`. The first step is to add our inputs and outputs to the module.

```module top (
input logic a,
input logic b,
output logic sum,
output logic carry
);```

SystemVerilog has logic operators that are syntactically similar to most C-influenced languages.

We can use the `assign` keyword along with our logic operators to implement our half adder. This assignment goes within our module definition.

````timescale 1ns / 1ps

module top (
input logic a,
input logic b,
output logic sum,
output logic carry
);

assign sum = a ^ b,
carry = a & b;

endmodule
```

Our half adder is done, let’s see it in action! We can start a simulation by looking for `Run Simulation` in the Flow Navigator on the left or from the Flow menu in the menu bar. We’ll select `Run Behavioral Simulation` since we’re not worried about timings for this design.

When we start the simulator, Vivado will elaborate the design, this means interpreting our HDL and determining how that design can be built. It’ll then open a new interface to let us interact with the simulated design.

The leftmost panel shows us the various modules in our design. The middle panel shows us the objects that are part of our selected module. The panel on the right opens up a wave viewer so we can watch the specific signals we’re interested in. Right now it shows our modules inputs and outputs.

It ran our simulation for some time too, a million picoseconds (1000 nanoseconds) have flown right by! We can use the zoom controls in the wave viewer to see everything that’s happened. So far, we haven’t set inputs to any value so the outputs are currently undefined.

To set `a` to a value, somewhat like we did with the toggle switches in Logicly, we can right click on `a` from the `Objects` panel or from the waveform viewer and choose `Force Constant...`

I’ll set `a` to 1 and `b` to `0` using this method. Then to continue simulation, we can use these time controls that are near the top of Vivado.

The play button will run the simulation indefinitely, which is not helpful in this case. I’ll instead edit the runtime field to run for 1 us (microsecond), and click the play with (T) to simulate for that specific amount of time.

After running one more microsecond, you can see the `sum` and `carry` did respond appropriately to our input on `a` and `b`. I can continue to change the values to validate the modules operation, but will leave it there for now.

Now we know that this design works, let’s look at it! In the Flow Navigator under `RTL ANALYSIS` we can click on `Open Elaborated Design` and look at the schematic that was built from the HDL.

Well doesn’t that look familiar! That will conclude this post of my Beginning Logic Design series, as always please leave any questions or feedback you may have in the comments! Keep tinkering!