A DIY Community for Tech, Science, and R&D

Join a culture of sharing, growth and collaboration. You can be a part of the maker movement!

Blinky with a button

Fipsy FPGA / Learning  / 4. Learning Projects / Blinky with a button

Find the code for this example on GitHub.

This example is almost identical to the Blinky 2Hz example except for some key details.

In particular, we no plan on using PIN14 as an input. So we no long tie it to ground. To do that, we comment out the following line, as shown:

//assign PIN14 = 0;

Next we change this line:

assign LEDn=flop2;

to this:

assign LEDn=!(flop2&!PIN14);

Where we do a bit-wise & operation of flop and PIN14. Not that PIN14 is inverted with the ‘!’ symbol, a logical negation.

After programming the FIPSY, the wiring is then this:

Ground to PIN2, voltage supply in to VCC/PIN1.

Now take another wire from voltage supply to PIN14 to stop the blinking of the on board LED (or use wire the voltage supply to PIN14 through a button or switch).

Now a few critical notes:

  • The operating voltage of this device is 3.3V, and any other voltage range (eg. 5V or 12V) will damage the device. The Raspberry Pi has a 3.3V output pin, that has been used to successfully power this device.
  • The use of a button in this example is for demonstration purpose only. FPGAs Only work in the digital domain. They don’t do analog directly (you will need an intermediary analog to digital(A/D) converter). Only digital, think communication protocols, or data from sensors that DO use an A/D converter.

Full code:

/* Blinky_Interrupt.v*/

module MakeFPGA_Top(
PIN7, PIN8, PIN9, PIN10,
PIN11, PIN12, PIN13, PIN14, PIN17, PIN18, PIN19, PIN20,
LEDn
);

// Define all of the above pins as available for general I/O
inout PIN7, PIN8, PIN9, PIN10, PIN11, PIN12, PIN13, PIN14, PIN17, PIN18, PIN19, PIN20;
// Except the LED, which is only an output, for which driving low lights the LED
output LEDn;

// At this level, all named signals are wires
wire PIN7, PIN8, PIN9, PIN10, PIN11, PIN12, PIN13, PIN14, PIN17, PIN18, PIN19, PIN20, LEDn;

// Instantiate a connection to the internal oscillator
wire INTERNAL_OSC;

defparam OSCH_inst.NOM_FREQ = "2.08"; // Must be one of the allowed frequencies (2.08MHz default)
OSCH OSCH_inst( .STDBY(1'b0), // Enable input, 0=Enabled, 1=Disabled (also disabled if Bandgap=OFF)
.OSC(INTERNAL_OSC), // Set the oscillator output to appear on the wire defined above
.SEDSTDBY() // This output is not required for normal use
);

// Create wires to connect the counter (see example application)
wire Out2Hz;

assign PIN7 = 0;
assign PIN8 = 0;
assign PIN9 = 0;
//assign PIN10 = 0;
//assign PIN11 = 0;
assign PIN12 = 0;
assign PIN13 = 0;
//assign PIN14 = 0;
assign PIN17 = 0;
assign PIN18 = 0;
assign PIN19 = 0;
//assign PIN20 = 0;
//assign LEDn = 0;

// Instantiate the counter/divider
FreqDiv20Bit FreqDiv20Bit_inst(
.CLOCK(INTERNAL_OSC), // Drive with internal oscillator
.RESET(PIN10), // Reset when chosen reset pin is high
.MSB(Out2Hz) // We expect 2 Hz out with 2MHz in
);

// View the signal on a chosen pin
assign PIN20 = Out2Hz;
// Also put the oscillator signal itself on a pin
assign PIN11 = INTERNAL_OSC;

reg flop1;
reg flop2;
//assign flop1 = Out2Hz;

initial
begin
flop2=0;
flop1=1;
end

always @ (posedge Out2Hz)
begin
flop1 <= flop2;
flop2 <= flop1;
end

assign LEDn=!(flop2&!PIN14);

//-----------------------------------------------------------------------------------------------
// End of module
//-----------------------------------------------------------------------------------------------

endmodule
/* FreqDiv20Bit.v

This module implements a 20-bit counter with only the most significant bit provided as
an output. In effect, this is a frequency divider for which the output toggles at a
rate equal to the clock frequency divided by 2^20. The clock is an input and is
applied to the sequential logic clock. Technically, the output is not a clock within
the FPGA, but a logic signal, although it will toggle like a clock. There is a reset
input that will set the count to zero on each clock edge for which it is set (logic high).
This reset will clear the output to logic low, and the count and output will remain
that way as long as reset is active. The reset input can therefore be used to stop the
output signal from toggling at an unpredictable point in the cycle. More complex logic
could be developed to provide a more predictable control.

*/

//-----------------------------------------------------------------------------------------------
// Module header with identification of connected signals
//-----------------------------------------------------------------------------------------------

module FreqDiv20Bit(CLOCK, RESET, MSB);

input CLOCK;
input RESET;
output MSB;

//-----------------------------------------------------------------------------------------------
// Signal definitions, registers, variables
//-----------------------------------------------------------------------------------------------

// Signal types for I/O
wire CLOCK;
wire RESET;
wire MSB;

// Internal count bits
reg [19:0] count;

//-----------------------------------------------------------------------------------------------
// Module logic definition
//-----------------------------------------------------------------------------------------------

// 20-Bit counter with synchronous reset
// With reset not in the sensitivity list, the reset is synchronous (on next clock edge)
// If reset were in the sensitivity list, the reset would be asynchronous, which might
// not be supported by the tool or the underlying hardware of the chip or both
// Without specifying bits and bit sizes of constants and variables, all defined bits are used.
// The tool logic synthesizer will warn that constants are 32-bit by default and it has
// to work out the impact for you. Yet writing it like this makes the code easier to
// understand in this simple example.
always @(posedge CLOCK)
begin
if(RESET)
count <= 0;
else
count <= count + 1;
end

// Connect the output
assign MSB = count[19];

//-----------------------------------------------------------------------------------------------
// End of module
//-----------------------------------------------------------------------------------------------

endmodule