Skip to content

Commit

Permalink
Set up CI for linting (#6)
Browse files Browse the repository at this point in the history
* Lint and format with ESLint and Prettier

* Add GitHub Actions lint workflow
  • Loading branch information
paulzzy authored Dec 30, 2023
1 parent c3347da commit 2146a84
Show file tree
Hide file tree
Showing 18 changed files with 955 additions and 272 deletions.
24 changes: 24 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
extends: ["eslint:recommended", "plugin:@docusaurus/recommended"],
overrides: [
{
env: {
node: true,
},
files: [".eslintrc.{js,cjs}"],
parserOptions: {
sourceType: "script",
},
},
],
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
},
rules: {},
};
26 changes: 26 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: CI

on:
push:
branches:
- main
pull_request:

jobs:
lint:
runs-on: ubuntu-22.04

steps:
- name: Checkout the repository
uses: actions/checkout@v3

- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: "20"

- name: Install dependencies
run: npm ci

- name: Lint the project
run: npm run lint
2 changes: 1 addition & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
presets: [require.resolve("@docusaurus/core/lib/babel/preset")],
};
67 changes: 33 additions & 34 deletions docs/DAV/lab-4.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# Lab 4

### Graphic Design Is My Passion

* [1: VGArbage](#1-vgarbage)
* [1.1: The VGA Constants](#11-the-vga-constants)
* [1.2: The Pixel Counters](#12-the-pixel-counters)
* [1.3: hsync and vsynv](#13-hsync-and-vsync)
* [1.4: The Pixel Color](#14-the-pixel-color)
* [1.5: The Top Level](#15-the-top-level)
* [2: I Can't Win](#2-i-cant-win)
* [3: Graphic Design Will Be Your Passion Too](#3-graphic-design-will-be-your-passion-too)
* [?: Extra Credit](#extra-credit)
- [1: VGArbage](#1-vgarbage)
- [1.1: The VGA Constants](#11-the-vga-constants)
- [1.2: The Pixel Counters](#12-the-pixel-counters)
- [1.3: hsync and vsynv](#13-hsync-and-vsync)
- [1.4: The Pixel Color](#14-the-pixel-color)
- [1.5: The Top Level](#15-the-top-level)
- [2: I Can't Win](#2-i-cant-win)
- [3: Graphic Design Will Be Your Passion Too](#3-graphic-design-will-be-your-passion-too)
- [?: Extra Credit](#extra-credit)

## Introduction

Expand All @@ -23,76 +24,74 @@ Link to Lecture 5

[Verilog Docs and FAQs](https://docs.google.com/document/d/1_8ruatZIb3sZb-3Kk3WOYC8Jzv4HvdwrTPZUGVupdVE/edit)


## Contact Us

You can contact the DAV leads on Discord.

**Claire Huang** (Discord: _zhiyujia_)
**Premkumar Giridhar** (Discord: _8bitrobot_)


## 1 VGArbage
## 1 VGArbage

To get started, [we’ve provided a skeleton for you](https://drive.google.com/file/d/1hvoNzdLyxhBUwM9_1KTYdDiDnigi52x9/view?usp=sharing).

You’ll observe that the gist of the VGA is mostly counters and some combinational logic. You keep track of where you currently are on the VGA using some counters in the sequential block (and some related `localparams`), and what actually displays on that part of the VGA is determined in the combinational block.

Your job now is to fill out the skeleton. We’ve labeled the four parts as **TODO(1), TODO(2), TODO(3), TODO(4)** for your reference. The actual tasks should be fairly straightforward (and they’re outlined in the skeleton!), but we’ll describe them in this lab spec as well for completeness.

### 1.1 The VGA Constants
### 1.1 The VGA Constants

Here, you’re presented with 8 constants that you need to find the values for. You can easily find these numbers by Googling _“VGA timing spec”_ or similar. You can also find them in our lecture slides :-)

Just keep in mind what each one is conceptually – you’ll need them later!

### 1.2 The Pixel Counters
### 1.2 The Pixel Counters

The pixel counters are the brain behind the VGA driver, and the sequential block triggered on the edge of our VGA clock is where we update them. If the reset button is pressed, you need to reset these counters to zero. Otherwise, you should increment the appropriate counter. The logic for counter increments is fairly straightforward – increment the horizontal counter `hc`, and if it gets too high, increment `vc` and set `hc` back to zero. You’ll need to use the parameters you defined earlier to figure out at what value of `hc` you need to move to the next line.

Also, keep in mind that `hc` and `vc` are zero-indexed when writing your conditions for incrementing them! If `hc` equals 800 at any point, you did something wrong :-)

### 1.3 `hsync` and `vsync`
### 1.3 `hsync` and `vsync`

Here, you’ll combinationally generate the `hsync` and `vsync` signals using the counter values. The parameters we defined earlier will come in handy here. Remember two things when figuring out the assignments:

* `hsync` and `vsync` should be HIGH for most of the time and driven LOW during the specific period within the blanking interval
* the duration of `hsync` and `vsync` is susceptible to off-by-one errors – make sure to double-check your conditions!
- `hsync` and `vsync` should be HIGH for most of the time and driven LOW during the specific period within the blanking interval
- the duration of `hsync` and `vsync` is susceptible to off-by-one errors – make sure to double-check your conditions!

### 1.4 The Pixel Color
### 1.4 The Pixel Color

Finally, you’ll use a combinational block to assign the pixel color outputs `red`, `green`, and `blue`. Remember to assign all the colors to 0 during blanking intervals and resets – otherwise, just assign the color values inputted via `input_red`, `input_green`, and `input_blue`.

### 1.5 The Top Level
### 1.5 The Top Level

This isn’t labeled in the skeleton because you need to make it yourself, but in addition to filling out the VGA skeleton, you need a top level to drive it. This will include the following tasks:

* Creating and instantiating a 25 MHz clock using a PLL
* Instantiating the VGA module
* Pin planning!
- Creating and instantiating a 25 MHz clock using a PLL
- Instantiating the VGA module
- Pin planning!

It’ll be fairly obvious if your module is working as expected, so you _probably_ don’t need to testbench for this one. But if you’re having weird timing issues and can’t figure out why, there’s nothing a testbench can’t help you figure out!

## 2 I Can’t Win
## 2 I Can’t Win

In this section, you’ll be implementing ping-pong RAM. If you recall from lecture, ping-pong RAM is a technique where our VGA reads from one memory buffer while our graphics driver writes to the other. This prevents the VGA from having its image change while it’s being read – a very common source of screen-tearing.

To implement this, it might be easier to first create the RAM as two arrays of registers, with one byte for each pixel on the screen (now you see why we used 8-bit color?). Once we have this working, we’ll replace the arrays with RAM IPs.

For this module, you should take in the following inputs:

* A clock, to allow synchronous changes of the read and write RAM,
* The address to write at, or `addrWrite`. This is dependent on the size of your array.
* Two values for `addrRead_h` and `addrRead_v`, which can be taken from your VGA module (remember the counters `hc` and `vc`?),
* And the data to write, or `dataWrite`. The size of this is dependent on the size of your colors - if your red, green, and blue pixels are 4 bits each, this will be 12 bits.
- A clock, to allow synchronous changes of the read and write RAM,
- The address to write at, or `addrWrite`. This is dependent on the size of your array.
- Two values for `addrRead_h` and `addrRead_v`, which can be taken from your VGA module (remember the counters `hc` and `vc`?),
- And the data to write, or `dataWrite`. The size of this is dependent on the size of your colors - if your red, green, and blue pixels are 4 bits each, this will be 12 bits.

Your module should output whatever was at the read address.

Now for the actual ping pong part. To switch the two RAMs, you can instantiate a 1 bit `writeEnable` register. Then, when `addrRead_h` and `addrRead_v` both reach zero (a.k.a. the start of the frame), the `writeEnable` register can be flipped. Make sure that the flipping is done sequentially, to keep everything in sync. In the combinational block, the selection of which RAM buffer to read/write can be determined based on `writeEnable`, and this address can be used to read the data out to the VGA module. That means that this ping pong RAM module will need to be instantiated in the top level where you instantiated your VGA module.

Wow, that was a lot. What do you even do with this ping pong RAM?
Wow, that was a lot. What do you even do with this ping pong RAM?

## 3 Graphic Design Will Be Your Passion Too
## 3 Graphic Design Will Be Your Passion Too

To encourage best practices, you’ll implement a very basic graphics module too. Don’t worry, you can just hardcode this part for now. This is just to show you a structure you can use for your final capstone project.

Expand All @@ -102,18 +101,18 @@ In the graphics module, you’ll want to take in the horizontal and vertical pos

The module should output the following:

* The color to be sent to the ping pong RAM,
* And the address to read/write from in the ping pong RAM.
- The color to be sent to the ping pong RAM,
- And the address to read/write from in the ping pong RAM.

(All of this is combinational, so there’s no clock involved in this one!)

To calculate the address - if the horizontal and vertical position are in the blanking interval, set the address to 0. Otherwise, you can find the address by calculating vertical position * (number of pixels in a row) + horizontal position.
To calculate the address - if the horizontal and vertical position are in the blanking interval, set the address to 0. Otherwise, you can find the address by calculating vertical position \* (number of pixels in a row) + horizontal position.

To calculate the color, you can just hard code it to return a certain color if it’s not in the blanking interval. If the horizontal and vertical positions are within the blanking interval, then the color should be all 0’s.

Now, it’s a matter of wiring up the inputs and outputs from the modules you created, and now you have a VGA using ping pong RAM!

## ? Extra credit
## ? Extra credit

If you want to go above and beyond on this lab, here’s a little exercise that will introduce you to blocking.

Expand All @@ -125,7 +124,7 @@ Remember that graphics module you created? You could in theory use the vertical

However! If we continued just like that, this mushroom would be very, very small. Each square would only be one pixel! What if we want to make this larger?

Well, we can implement a technique called blocking! In the top level, you can assign some wires to be a smaller version of the horizontal position and vertical position.
Well, we can implement a technique called blocking! In the top level, you can assign some wires to be a smaller version of the horizontal position and vertical position.

```verilog
// horizontal_position ranges from 0 to 799
Expand Down
22 changes: 11 additions & 11 deletions docs/DAV/lab-5.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Lab 5
### A Phone Named Michael

### A Phone Named Michael

* [0: In DAV No One Can Hear You Scream](#0-in-dav-no-one-can-hear-you-scream)
* [1: Anyways, Don't Cry](#1-anyways-dont-cry)
* [2: It's So Sample](#2-its-so-sample)
- [0: In DAV No One Can Hear You Scream](#0-in-dav-no-one-can-hear-you-scream)
- [1: Anyways, Don't Cry](#1-anyways-dont-cry)
- [2: It's So Sample](#2-its-so-sample)

## Introduction

Expand All @@ -21,7 +21,7 @@ You can contact the DAV leads on Discord.
**Claire Huang** (Discord: _zhiyujia_)
**Premkumar Giridhar** (Discord: _8bitrobot_)

## 0 In DAV No One Can Hear You Scream
## 0 In DAV No One Can Hear You Scream

For DAV, we’ll be working with mics that look like this one below. This is an analog microphone. It has two input pins, VCC and GND, and an output pin through which it spits out an _analog_ voltage corresponding to the mic input intensity (a.k.a. the volume). If you want to know more about how microphones work, consult [this article](https://mynewmicrophone.com/how-do-microphones-work-a-helpful-illustrated-guide/) (and perhaps ChatGPT for a summary).

Expand All @@ -31,16 +31,16 @@ But wait! You might be thinking, _aren’t we learning about digital design?_ Yo

So anyways, onto the ADC we go!

## 1 Anyways, Don’t Cry
## 1 Anyways, Don’t Cry

In order to use the ADC on our FPGAS, we can just use an IP! It’s called the **ADC Controller for DE-series Boards**.

In the IP settings, you’ll want to specify these:

* DE-Series Board: **DE10-Lite**
* ADC Clock Frequency: **10.0 MHz** (this should be filled in already)
* Number of channels: **1**
* System Clock Frequency: **50**
- DE-Series Board: **DE10-Lite**
- ADC Clock Frequency: **10.0 MHz** (this should be filled in already)
- Number of channels: **1**
- System Clock Frequency: **50**

The files will be generated for you, and they’re all you need to get started with your ADC. However, you need to manually add the `.qip` file to your project - and after that, you can find the template within the QIP with the same name as your ADC instantiation. The ADC comes with eight channels, but we’ll only be using one of them (CH0).

Expand All @@ -50,7 +50,7 @@ To set up your microphone, you’ll want to use your breadboard. (If you need a

Then, you’ll want to wire up the VCC pin on the microphone to **VCC5** (the 5-volt power pin) on the board, the GND pin on the microphone to **GND**, and the OUT pin to **ADC_IN0**. Note that the little labels on the board are _incorrect_ for some pins, so you should use the screenshot above as your source of where the pins are.

## 2 It’s So Sample
## 2 It’s So Sample

To get a feel for how your microphone works, let’s test the waters a little bit! Your job is to get the output of your microphone onto the LEDs of your board. The ADC wants a clock (to sample) and a reset button, and it will output the microphone intensity to `CH0`. Then, display the magnitude on your LEDs. You can do that by using the output of the ADC outstream to right-shift `10'b1000000000` by some amount; due to sign-extension, this will cause light up more LEDs when the mic input is louder! (If the magnitude of the mic output is too large, all of the LEDs will always be lit up, so you may want to scale and/or shift your ADC output value by some experimentally derived constant.)

Expand Down
Loading

0 comments on commit 2146a84

Please sign in to comment.