Combinational Logic II

More Flexible Functions

The questions below are due on Wednesday September 11, 2024; 11:59:00 PM.
 
You are not logged in.

Please Log In for full access to the web site.
Note that this link will take you to an external site (https://shimmer.mit.edu) to authenticate, and then you will be redirected back to this page.

In the previous assignment, you constructed a circuit comprised of logic gates. While it's a good first exercise in SystemVerilog and digital design, it is quite divorced from how one usually goes about doing digital design in practice:

  1. As humans, we rarely approach a function or algorithm knowing the solution in a Boolean Algebraic format. We are much more often thinking of it as numbers or logical flow. We want to be able to add two numbers, or perhaps make a flow-control decision (an "if/else"), for example. It is important to recognize that the problem can be reduced to these fundamental operations (and we'll get a bit of practice with that later in this week's assignments), but doing that reduction should be the job of computational design tools.
  2. FPGAs are reconfigurable logic circuits and are actually not really even comprised of AND, OR, NAND, etc... gates, despite those being the fundamental operations in Boolean algebra. They are instead comprised of small programmable logic modules which perform logic functions. Those logic functions can be standard two-input AND, OR, NAND, etc, but they can do much more. In fact, each of the tens-of-thousands of "logic blocks" on your FPGA can be programmed to express any six-input digital logic function (and there are 2^{64} possible functions to express - about 18.4 million-trillion possibilites).

One common thing we may want to do is "choice" or flow-control logic, aka if/else type logic. There's two general ways to do this. The first way is using an always_comb block is probably the most familiar to you. It looks something like this:

//assume a,b,c,d have been previously declared and are of appropriate sizes (example logic [7:0] a;)
always_comb begin
    if (c>d)begin
        a = b;
    end else begin
        a = ~b;
    end
end

This is nice and readable. If desired you can also use ternary style operations. The SV below does the same as the SV above.

always_comb begin
    a = (c>d)?b:~b;
end

Just like on the previous page, you can also not use always_comb and instead just do an assign statement. Unfortunately, there's no way do a if/else style syntax with assign statements, but you can still use ternary operations. So for example:

assign a = (c>d)?b:~b;

For some practice, consider the C code below, which expresses a simple logical operation using inputs a, b, and c and returns an output, which we'll call d.

uint8_t d2(uint8_t a, uint8_t b, uint8_t c) {
    if (a > b) {
        return 4;
    } else if (a == b) {
        return 11;
    } else if (b - a < 13) {
        return 3;
    } else {
        return c;
    }
}

Write an equivalent SystemVerilog implementation of this function above. Have its output port be called d.

Once you're done, move on to the next part of this week's assignments :D