| 1 |
50 |
dgisselq |
////////////////////////////////////////////////////////////////////////////////
|
| 2 |
|
|
//
|
| 3 |
|
|
// Filename: clrled.v
|
| 4 |
|
|
//
|
| 5 |
|
|
// Project: OpenArty, an entirely open SoC based upon the Arty platform
|
| 6 |
|
|
//
|
| 7 |
|
|
// Purpose: The ARTY contains 4 Color LEDs. Each color LED is composed of
|
| 8 |
|
|
// three LEDs: one red, one blue, and one green. These LEDs need
|
| 9 |
|
|
// to be toggled in a PWM manner in order to create varying amounts of
|
| 10 |
|
|
// reds, blues, greens, and other colors with varying components of red,
|
| 11 |
|
|
// green, and blue. This Verilog core creates a bus controlled core
|
| 12 |
|
|
// so that these LEDs can be controlled by any bus master. While the core
|
| 13 |
|
|
// is ostensibly controlled via a wishbone bus, none of the control wires
|
| 14 |
|
|
// are wishbone wires, save the i_stb wire. Address wires are not needed,
|
| 15 |
|
|
// as this core only implements a single address. Stall is permanently
|
| 16 |
|
|
// set to zero. Ack is always on the clock after STB is true (but not set
|
| 17 |
|
|
// here), and the output data is given by o_data. See fastio.v for how to
|
| 18 |
|
|
// connect this to a wishbone bus.
|
| 19 |
|
|
//
|
| 20 |
|
|
// The core also accepts 9-bits from a counter created elsewhere. This
|
| 21 |
|
|
// counter is created quite simply, and phase is irrelevant for our
|
| 22 |
|
|
// purposes here. Thy reason why we don't create the counter within this
|
| 23 |
|
|
// core is because the same counter can also be shared with the other
|
| 24 |
|
|
// clrled cores. The code to generate this counter is quite simple:
|
| 25 |
|
|
//
|
| 26 |
|
|
// reg [8:0] counter;
|
| 27 |
|
|
// always @(posedge i_clk)
|
| 28 |
|
|
// counter <= counter + 9'h1;
|
| 29 |
|
|
//
|
| 30 |
|
|
//
|
| 31 |
|
|
// The core creates and maintains one 32-bit register on the bus. This
|
| 32 |
|
|
// register contains four bytes:
|
| 33 |
|
|
//
|
| 34 |
|
|
// Byte 0 (MSB)
|
| 35 |
|
|
// Contains the most significant bits of the red, green, and blue
|
| 36 |
|
|
// color. Since using these bits sets the CLRLED to be *very*
|
| 37 |
|
|
// bright, the design is set to assume they will rarely be used.
|
| 38 |
|
|
//
|
| 39 |
|
|
// Byte 1
|
| 40 |
|
|
// The red control. The higher the value, the brighter the red
|
| 41 |
|
|
// component will be.
|
| 42 |
|
|
//
|
| 43 |
|
|
// Byte 2 Blue control.
|
| 44 |
|
|
// Byte 3 Green control.
|
| 45 |
|
|
//
|
| 46 |
|
|
// As examples, setting this register to 0x0ffffff will produce a bright
|
| 47 |
|
|
// white light from the color LED. Setting it to 0x070000 will produce
|
| 48 |
|
|
// a dimmer red light.
|
| 49 |
|
|
//
|
| 50 |
|
|
// Creator: Dan Gisselquist, Ph.D.
|
| 51 |
|
|
// Gisselquist Technology, LLC
|
| 52 |
|
|
//
|
| 53 |
|
|
////////////////////////////////////////////////////////////////////////////////
|
| 54 |
|
|
//
|
| 55 |
|
|
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
|
| 56 |
|
|
//
|
| 57 |
|
|
// This program is free software (firmware): you can redistribute it and/or
|
| 58 |
|
|
// modify it under the terms of the GNU General Public License as published
|
| 59 |
|
|
// by the Free Software Foundation, either version 3 of the License, or (at
|
| 60 |
|
|
// your option) any later version.
|
| 61 |
|
|
//
|
| 62 |
|
|
// This program is distributed in the hope that it will be useful, but WITHOUT
|
| 63 |
|
|
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
|
| 64 |
|
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
| 65 |
|
|
// for more details.
|
| 66 |
|
|
//
|
| 67 |
|
|
// You should have received a copy of the GNU General Public License along
|
| 68 |
|
|
// with this program. (It's in the $(ROOT)/doc directory, run make with no
|
| 69 |
|
|
// target there if the PDF file isn't present.) If not, see
|
| 70 |
|
|
// <http://www.gnu.org/licenses/> for a copy.
|
| 71 |
|
|
//
|
| 72 |
|
|
// License: GPL, v3, as defined and found on www.gnu.org,
|
| 73 |
|
|
// http://www.gnu.org/licenses/gpl.html
|
| 74 |
|
|
//
|
| 75 |
|
|
//
|
| 76 |
|
|
////////////////////////////////////////////////////////////////////////////////
|
| 77 |
|
|
//
|
| 78 |
|
|
//
|
| 79 |
|
|
module clrled(i_clk, i_stb, i_data, i_counter, o_data, o_led);
|
| 80 |
|
|
input i_clk, i_stb;
|
| 81 |
|
|
input [31:0] i_data;
|
| 82 |
|
|
input [8:0] i_counter;
|
| 83 |
|
|
output wire [31:0] o_data;
|
| 84 |
|
|
output reg [2:0] o_led;
|
| 85 |
|
|
|
| 86 |
|
|
//
|
| 87 |
|
|
//
|
| 88 |
|
|
// If i_counter isn't available, just build one as in:
|
| 89 |
|
|
//
|
| 90 |
|
|
// reg [8:0] counter;
|
| 91 |
|
|
// always @(posedge i_clk) counter <= counter + 1'b1;
|
| 92 |
|
|
//
|
| 93 |
|
|
|
| 94 |
|
|
wire [31:0] w_clr_led;
|
| 95 |
|
|
reg [8:0] r_clr_led_r, r_clr_led_g, r_clr_led_b;
|
| 96 |
|
|
|
| 97 |
|
|
initial r_clr_led_r = 9'h003; // Color LED on the far right
|
| 98 |
|
|
initial r_clr_led_g = 9'h000;
|
| 99 |
|
|
initial r_clr_led_b = 9'h000;
|
| 100 |
|
|
|
| 101 |
|
|
always @(posedge i_clk)
|
| 102 |
|
|
if (i_stb)
|
| 103 |
|
|
begin
|
| 104 |
|
|
r_clr_led_r <= { i_data[26], i_data[23:16] };
|
| 105 |
|
|
r_clr_led_g <= { i_data[25], i_data[15: 8] };
|
| 106 |
|
|
r_clr_led_b <= { i_data[24], i_data[ 7: 0] };
|
| 107 |
|
|
end
|
| 108 |
|
|
|
| 109 |
|
|
assign o_data = { 5'h0,
|
| 110 |
|
|
r_clr_led_r[8], r_clr_led_g[8], r_clr_led_b[8],
|
| 111 |
|
|
r_clr_led_r[7:0], r_clr_led_g[7:0], r_clr_led_b[7:0]
|
| 112 |
|
|
};
|
| 113 |
|
|
|
| 114 |
|
|
wire [8:0] rev_counter;
|
| 115 |
|
|
assign rev_counter[8] = i_counter[0];
|
| 116 |
|
|
assign rev_counter[7] = i_counter[1];
|
| 117 |
|
|
assign rev_counter[6] = i_counter[2];
|
| 118 |
|
|
assign rev_counter[5] = i_counter[3];
|
| 119 |
|
|
assign rev_counter[4] = i_counter[4];
|
| 120 |
|
|
assign rev_counter[3] = i_counter[5];
|
| 121 |
|
|
assign rev_counter[2] = i_counter[6];
|
| 122 |
|
|
assign rev_counter[1] = i_counter[7];
|
| 123 |
|
|
assign rev_counter[0] = i_counter[8];
|
| 124 |
|
|
|
| 125 |
|
|
always @(posedge i_clk)
|
| 126 |
|
|
o_led <= { (rev_counter[8:0] < r_clr_led_r),
|
| 127 |
|
|
(rev_counter[8:0] < r_clr_led_g),
|
| 128 |
|
|
(rev_counter[8:0] < r_clr_led_b) };
|
| 129 |
|
|
|
| 130 |
|
|
endmodule
|