Skip to content

Instantly share code, notes, and snippets.

@dwaq
Created November 26, 2019 17:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dwaq/602f5aabfb8b604d0402d9a776e8e5fb to your computer and use it in GitHub Desktop.
Save dwaq/602f5aabfb8b604d0402d9a776e8e5fb to your computer and use it in GitHub Desktop.
Traffic Light project in Verilog using APIO
[env]
board = TinyFPGA-BX
// Verilog implementation of the CD4017 CMOS Counter
module CD4017 (
input CLK,
output wire [9:0] OUT
);
// start output at 1
reg[9:0] counter = 10'd1;
always @(posedge CLK)
begin
// shift counter each clock
counter <= counter << 1;
// when it shifts to the last position (to digit 9),
// reset to 1
if(counter == 10'b1000000000)
counter <= 10'd1;
end
assign OUT = counter;
endmodule
// fpga4student.com: FPGA projects, VHDL projects, Verilog projects
// Verilog project: Verilog code for clock divider on FPGA
// divide clock from 16Mhz to 1Hz
module Clock_divider (
input clock_in,
output wire clock_out
);
// math is easy to get 1Hz, just divide by frequency
parameter DIVISOR = 24'd16000000;
// to reduce simulation time, use this divisor instead:
//parameter DIVISOR = 24'd16;
// 2^24 = 16,777,216 which is greater that the 16,000,000 we need to store
reg[23:0] counter=24'd0;
always @(posedge clock_in)
begin
// increase counter each clock cycle
counter <= counter + 24'd1;
// once we reach the end of the counter, reset it
if(counter >= (DIVISOR-1))
counter <= 24'd0;
end
// for lower half of counter, set clock out to 0
// for upper half of counter, set clock out to 1
assign clock_out = (counter < (DIVISOR/2)) ? 1'b0 : 1'b1;
endmodule
pip install apio==0.4.0b3 tinyprog
apio install system scons icestorm drivers
apio drivers --serial-enable
@pause
pip install apio==0.4.0b3 tinyprog
apio install system scons icestorm drivers
apio drivers --serial-enable
###############################################################################
#
# TinyFPGA BX constraint file (.pcf)
#
###############################################################################
#
# Copyright (c) 2018, Luke Valenty
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and documentation are those
# of the authors and should not be interpreted as representing official policies,
# either expressed or implied, of the <project name> project.
#
###############################################################################
####
# TinyFPGA BX information: https://github.com/tinyfpga/TinyFPGA-BX/
####
# Left side of board
set_io --warn-no-port PIN_1 A2
set_io --warn-no-port PIN_2 A1
set_io --warn-no-port PIN_3 B1
set_io --warn-no-port PIN_4 C2
set_io --warn-no-port PIN_5 C1
set_io --warn-no-port PIN_6 D2
set_io --warn-no-port PIN_7 D1
set_io --warn-no-port PIN_8 E2
set_io --warn-no-port PIN_9 E1
set_io --warn-no-port PIN_10 G2
set_io --warn-no-port PIN_11 H1
set_io --warn-no-port PIN_12 J1
set_io --warn-no-port PIN_13 H2
# Right side of board
set_io --warn-no-port PIN_14 H9
set_io --warn-no-port PIN_15 D9
set_io --warn-no-port PIN_16 D8
set_io --warn-no-port PIN_17 C9
set_io --warn-no-port PIN_18 A9
set_io --warn-no-port PIN_19 B8
set_io --warn-no-port PIN_20 A8
set_io --warn-no-port PIN_21 B7
set_io --warn-no-port PIN_22 A7
set_io --warn-no-port PIN_23 B6
set_io --warn-no-port PIN_24 A6
# SPI flash interface on bottom of board
set_io --warn-no-port SPI_SS F7
set_io --warn-no-port SPI_SCK G7
set_io --warn-no-port SPI_IO0 G6
set_io --warn-no-port SPI_IO1 H7
set_io --warn-no-port SPI_IO2 H4
set_io --warn-no-port SPI_IO3 J8
# General purpose pins on bottom of board
set_io --warn-no-port PIN_25 G1
set_io --warn-no-port PIN_26 J3
set_io --warn-no-port PIN_27 J4
set_io --warn-no-port PIN_28 G9
set_io --warn-no-port PIN_29 J9
set_io --warn-no-port PIN_30 E8
set_io --warn-no-port PIN_31 J2
# LED
set_io --warn-no-port LED B3
# USB
set_io --warn-no-port USBP B4
set_io --warn-no-port USBN A4
set_io --warn-no-port USBPU A3
# 16MHz clock
set_io --warn-no-port CLK B2 # input
# my configuration
set_io --warn-no-port GREEN A1
set_io --warn-no-port YELLOW B1
set_io --warn-no-port RED C2
// look in pins.pcf for all the pin names on the TinyFPGA BX board
module top (
input CLK, // 16MHz clock
output USBPU, // USB pull-up resistor
output GREEN,
output YELLOW,
output RED
);
// drive USB pull-up resistor to '0' to disable USB
assign USBPU = 0;
// 1Hz divided down clock
wire one_hertz;
// output of CD4017
wire [9:0] data;
// use clock divider module to divide clock from 16Mhz to 1Hz
Clock_divider inst1 (
.clock_in (CLK),
.clock_out (one_hertz)
);
CD4017 inst2 (
.CLK (one_hertz),
.OUT (data)
);
// set outputs using reduction OR
// first 4 (0-3) are green
assign GREEN = |data[3:0];
// next 2 are yellow
assign YELLOW = |data[5:4];
// last 4 are red
assign RED = |data[9:6];
endmodule
`default_nettype none
`define DUMPSTR(x) `"x.vcd`"
`timescale 100 ns / 10 ns
// Testbench Verilog code
module top_tb();
// Simulation time: 20us (200 * 100ns)
// remember to change lines 10-12 in clock_divider.v
// to reduce run time
parameter DURATION = 200;
// Clock signal
reg clk = 1;
always #0.5 clk = ~clk;
// Inputs
reg clock_in;
// Outputs
wire green, yellow, red;
// Instantiate the Unit Under Test (UUT)
top uut (
.CLK(clk),
.GREEN(green),
.YELLOW(yellow),
.RED(red)
);
initial begin
// File were to store the simulation results
$dumpfile(`DUMPSTR(`VCD_OUTPUT));
$dumpvars(0, top_tb);
#(DURATION) $display("End of simulation");
$finish;
end
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment