Objective

image-20220107234755242

Terminal - Frostivator

Challenge

Grody Goiterson is by the elevator in the lobby of Frost Tower:

image-20220107224522444

Hrmph. Snrack! Pthbthbthb.

Gnerphk. Well, on to business.

I’m Grody Goiterson. … It’s a family name.

So hey, this is the Frostavator. It runs on some logic chips… that fell out.

I put them back in, but I must have mixed them up, because it isn’t working now.

If you don’t know much about logic gates, it’s something you should look up.

If you help me run the elevator, maybe I can help you with something else.

I’m pretty good with FPGAs, if that’s worth something to ya’.

He provides a hint as well in the badge:

The Frostivator shows No Power:

image-20220107224801819

Clicking the Open Panel button shows a series of logic gates inside:

image-20220107224835052

Solution

I can’t change the inputs, and I need all three outputs to be powered. These gates each have an output that depends on the two inputs. This table shows how each works:

  a=0
b=0
a=1
b=0
a=0
b=1
a=1
b=1
AND
and
0 0 0 1
OR
or
0 1 1 1
XOR
xor
0 1 1 0
NAND
nand
1 1 1 0
NOR
nor
1 0 0 0
XNOR
xnor
1 0 0 1

I’ll shuffle them around until I find a solution:

image-20220107230047988

FPGA Programming

Hints

Grody is ready to talk about FPGAs:

Oooo… That’s it!

A deal’s a deal. Let’s talk FPGA.

First, did you know there are people who do this stuff for fun??

I mean, I’m more into picking on other trolls for fun, but whatever.

Also, that Prof. Petabyte guy is giving a talk about FPGAs. Weirdo.

So hey, good luck or whatever.

He also unlocks two hints in the badge:

Challenge

All three trolls on the roof are talking strangely about home planets:

image-20220107231228552

Rose Mold:

I’m Rose Mold. What planet are you from?

Hey, way to go climbing the stairs. You do know you can teleport, right?

Or just use the Frostavator.

n00bs…

Numby Chiblain:

Klatu Barada Nikto!

I’m Numby Chilblain.

And Crunch Squishter:

Greetings Earthling! I’m Crunchy Squishter.

Hey, could you help me get this device on the table working? We’ve cobbled it together with primitive parts we’ve found on your home planet.

We need an FPGA though - and someone who knows how to program them.

If you haven’t talked with Grody Goiterson by the Frostavator, you might get some FPGA tips there.

The FPGA Programming terminal presents an exercise:

image-20220107231425466Click for full size image

Solution

To do this problem, unless you are already familiar with FPGAs, watching the presentation from professor Qwerty is a must.

I’ll walk through my solution in detail here:

I started by trying to make code that ignored the freq input and just worked for a given freq, 500Hz, which resulted in the following code:

// Note: For this lab, we will be working with QRP Corporation's CQC-11 FPGA.
// The CQC-11 operates with a 125MHz clock.
// Your design for a tone generator must support the following 
// inputs/outputs:
// (NOTE: DO NOT CHANGE THE NAMES. OUR AUTOMATED GRADING TOOL
// REQUIRES THE USE OF THESE NAMES!)
// input clk - this will be connected to the 125MHz system clock
// input rst - this will be connected to the system board's reset bus
// input freq - a 32 bit integer indicating the required frequency
//              (0 - 9999.99Hz) formatted as follows:
//              32'hf1206 or 32'd987654 = 9876.54Hz
// output wave_out - a square wave output of the desired frequency
// you can create whatever other variables you need, but remember
// to initialize them to something!

`timescale 1ns/1ns
module tone_generator (
    input clk,
    input rst,
    input [31:0] freq,
    output wave_out
);
    // ---- DO NOT CHANGE THE CODE ABOVE THIS LINE ---- 
    // ---- IT IS NECESSARY FOR AUTOMATED ANALYSIS ----
    // TODO: Add your code below. 
    // Remove the following line and add your own implementation. 
    // Note: It's silly, but it compiles...
    reg[31:0] counter;
    reg wave;
    assign wave_out = wave;
    
    always @(posedge clk or posedge rst)
    begin
        if(rst==1)
            begin
                counter <= 0;
                wave <= 0;
            end
        else
            begin
                if(counter >= 125000 || freq == 123456)
                    begin
                        counter <= 1;
                        wave <= wave ^ 1'b1;
                    end
                else
                    counter <= counter + 1;
            
            end
    end
endmodule

The counter is 125000 because I know that 125MHz triggers every 0.000000008 seconds, and I wanted 0.002 seconds, so that’s 0.002 * 125,000,000 = 250000. That was off by a factor of two, so I adjusted. That factor of two is that I want there to be two flips in my wave for each full cycle.

The check on freq == 123456 was just because the program required that I used all inputs for it to compile, and this shouldn’t trigger while I’m targeting 500MHz.

Once that worked, I tried 1000Hz and 2000Hz. My method seemed solid.

To get it to adjust based on freq, I found that the counter should flop when counter / freq >= 62500000. To make that work in this all integer world, I set the condition to if(counter * freq >= 62500000). I was getting frequencies off by a factor of 100, when I realized that the int value on freq is supposed to include two decimal places. I needed to increase that threshold by a factor of 100, which works fine, once I realized how to write a 64 bit register to hold the constant.

My final code was:

// Note: For this lab, we will be working with QRP Corporation's CQC-11 FPGA.
// The CQC-11 operates with a 125MHz clock.
// Your design for a tone generator must support the following 
// inputs/outputs:
// (NOTE: DO NOT CHANGE THE NAMES. OUR AUTOMATED GRADING TOOL
// REQUIRES THE USE OF THESE NAMES!)
// input clk - this will be connected to the 125MHz system clock
// input rst - this will be connected to the system board's reset bus
// input freq - a 32 bit integer indicating the required frequency
//              (0 - 9999.99Hz) formatted as follows:
//              32'hf1206 or 32'd987654 = 9876.54Hz
// output wave_out - a square wave output of the desired frequency
// you can create whatever other variables you need, but remember
// to initialize them to something!

`timescale 1ns/1ns
module tone_generator (
    input clk,
    input rst,
    input [31:0] freq,
    output wave_out
);
    // ---- DO NOT CHANGE THE CODE ABOVE THIS LINE ---- 
    // ---- IT IS NECESSARY FOR AUTOMATED ANALYSIS ----
    // TODO: Add your code below. 
    // Remove the following line and add your own implementation. 
    // Note: It's silly, but it compiles...
    reg[31:0] counter;
    reg wave;
    assign wave_out = wave;
    
    always @(posedge clk or posedge rst)
    begin
        if(rst==1)
            begin
                counter <= 0;
                wave <= 0;
            end
        else
            begin
                if(counter * freq >= 64'd6250000000)
                    begin
                        counter <= 1;
                        wave <= wave ^ 1'b1;
                    end
                else
                    counter <= counter + 1;
            
            end
    end
endmodule