// ================================================================== | |||||
// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<< | |||||
// ------------------------------------------------------------------ | |||||
// Copyright (c) 2022 by Ampelsteuerungsgruppe | |||||
// | |||||
// -------------------------------------------------------------------- | |||||
// | |||||
// Project: iCE5UP 5K RGB LED Steuerung | |||||
// File: LED_control.sv | |||||
// Title: LED Ampelsteuerung | |||||
// Description: Creates RGB PWM per data input | |||||
// | |||||
// | |||||
// -------------------------------------------------------------------- | |||||
// | |||||
//------------------------------------------------------------ | |||||
// Notes: | |||||
// | |||||
// | |||||
//------------------------------------------------------------ | |||||
// Development History: | |||||
// | |||||
// __DATE__ _BY_ _____REV_ _DESCRIPTION___________________________ | |||||
// 17.02.22 AmpelGr 1.0 Initial design for Lattice Radiant Ampelsteuerung | |||||
// | |||||
//------------------------------------------------------------ | |||||
// Dependencies: | |||||
// | |||||
// | |||||
// | |||||
//------------------------------------------------------------ | |||||
module LED_control1 ( | |||||
// inputs | |||||
input wire clk12M, // 12M clock | |||||
input wire enable, // Asynchronous enable/disable wire | |||||
input wire [7:0] data_input, // for selecting color using sensor data | |||||
input wire data_valid, // Data on Parallelport is valid on posedge | |||||
//outputs | |||||
output reg red_pwm, // Red LED | |||||
output reg grn_pwm, // Green LED | |||||
output reg alarm // Alarmmeldung | |||||
); | |||||
//------------------------------ | |||||
// INTERNAL SIGNAL DECLARATIONS: | |||||
//------------------------------ | |||||
// parameters (constants) | |||||
parameter on_hi = 2'b10; | |||||
parameter on_lo = 2'b01; | |||||
parameter off = 2'b00; | |||||
parameter Brightness=4'b0111; //50% Brightness | |||||
// wires (assigns) | |||||
wire [4:0] red_intensity; | |||||
wire [4:0] grn_intensity; | |||||
wire clk24M; | |||||
wire LOCK; | |||||
// regs (always) | |||||
reg [1:0] RGB_color_s; // selected Color | |||||
reg [3:0] Brightness_s; | |||||
reg [1:0] red_set; // hi/lo/off | |||||
reg [1:0] grn_set; | |||||
reg [17:0] red_peak; // LED 'on' peak intensity (high precision) | |||||
reg [17:0] grn_peak; | |||||
reg [17:0] curr_red; // current LED intensity ( /256 = PWM duty cycle) | |||||
reg [17:0] curr_grn; | |||||
reg [17:0] pwm_count; // PWM counter | |||||
reg [7:0] count = 8'b0; | |||||
//------------------------------ | |||||
// PLL Instantiation | |||||
//------------------------------ | |||||
//Block to reset the PLL initially | |||||
pll_24M __(.ref_clk_i(clk12M ), .rst_n_i(~enable), .lock_o(LOCK), .outcore_o( ), .outglobal_o(clk24M)); | |||||
// Capture stable parameters in local clock domain | |||||
always @ (posedge clk24M or posedge enable) | |||||
if (enable) begin | |||||
RGB_color_s <= 2'b00; //turn off | |||||
Brightness_s <= 4'b0000; | |||||
alarm <= 0; | |||||
end else if(!alarm) begin | |||||
if(data_valid) begin | |||||
if(data_input <100) begin | |||||
RGB_color_s <= 2'b10; // set green | |||||
Brightness_s <= Brightness; | |||||
end else if(data_input >168) begin | |||||
alarm <=1'b1; | |||||
end else begin | |||||
RGB_color_s <= 2'b11; // set yellow | |||||
Brightness_s <= Brightness; | |||||
end | |||||
end | |||||
end else begin | |||||
RGB_color_s <= 2'b01; // set Color red | |||||
Brightness_s <= Brightness; | |||||
end | |||||
// interpret 'brightness' setting | |||||
assign red_intensity = Brightness_s + 1'b1; | |||||
assign grn_intensity = Brightness_s + 1'b1; | |||||
// interpret 'color' setting | |||||
always @ (RGB_color_s) | |||||
case (RGB_color_s) | |||||
2'b01: begin red_set <= on_hi; grn_set <= off; end //Red | |||||
4'b10: begin red_set <= off; grn_set <= on_hi; end //Green | |||||
4'b11: begin red_set <= on_hi; grn_set <= on_hi; end //Yellow | |||||
default: begin red_set <= off; grn_set <= off; end //2'b00 off | |||||
endcase | |||||
// set peak values per 'brightness' and 'color' | |||||
// when color setting is 'on_lo', then peak intensity is divided by 2 | |||||
always @ (posedge clk24M or posedge enable) | |||||
if (enable) begin | |||||
red_peak <= 18'b0; | |||||
end else begin | |||||
case (red_set) | |||||
on_hi: red_peak <= {red_intensity, 13'h000}; // 100% | |||||
on_lo: red_peak <= {1'b0,red_intensity, 12'h000}; // 50% | |||||
default: red_peak <= 18'h00000; | |||||
endcase | |||||
end | |||||
always @ (posedge clk24M or posedge enable) | |||||
if (enable) begin | |||||
grn_peak <= 32'b0; | |||||
end else begin | |||||
case (grn_set) | |||||
on_hi: grn_peak <= {grn_intensity, 13'h000}; // 100% | |||||
on_lo: grn_peak <= {1'b0,grn_intensity, 12'h000}; // 50% | |||||
default: grn_peak <= 18'h00000; | |||||
endcase | |||||
//$monitor("grn_peak=%d",grn_peak); | |||||
end | |||||
// set PWM duty cycle. 8-bit resolution 0x100 is 100% on | |||||
always @ (posedge clk24M or posedge enable) | |||||
if (enable) begin | |||||
curr_red <= 18'b0; | |||||
curr_grn <= 18'b0; | |||||
end else begin | |||||
curr_red <= red_peak; | |||||
curr_grn <= grn_peak; | |||||
end | |||||
// generate PWM outputs | |||||
always @ (posedge clk24M or posedge enable) | |||||
if (enable) begin | |||||
pwm_count <= 18'b0; | |||||
red_pwm <= 0; | |||||
grn_pwm <= 0; | |||||
end else begin | |||||
if(pwm_count < 131071) | |||||
pwm_count <= pwm_count + 1; | |||||
else | |||||
pwm_count <= 0; | |||||
if(pwm_count < curr_red) | |||||
red_pwm <= 1; | |||||
else | |||||
red_pwm <= 0; | |||||
if(pwm_count < curr_grn) | |||||
grn_pwm <= 1; | |||||
else | |||||
grn_pwm <= 0; | |||||
end | |||||
endmodule // LED_control |
module led_top ( | |||||
input wire clk12M, | |||||
input wire rst, | |||||
input wire [7:0] data_input, | |||||
input wire data_valid, | |||||
output reg REDn, | |||||
output reg GRNn, | |||||
output reg RED, | |||||
output reg GRN, | |||||
output reg alarm | |||||
); | |||||
wire red_pwm; | |||||
wire grn_pwm; | |||||
defparam U1.on_hi = 2'b10; | |||||
defparam U1.on_lo = 2'b01; | |||||
defparam U1.off = 2'b00; | |||||
defparam U1.Brightness = 4'b0111; // 50% Brightness | |||||
defparam U2.RGB0_CURRENT = "0b111111"; | |||||
defparam U2.RGB1_CURRENT = "0b111111"; | |||||
defparam U2.RGB2_CURRENT = "0b111111"; | |||||
LED_control1 U1 (.clk12M(clk12M),.enable(rst),.data_input(data_input),.data_valid(data_valid),.red_pwm(red_pwm),.grn_pwm(grn_pwm),.alarm(alarm)); | |||||
RGB U2 (.CURREN('b1),.RGB0PWM(),.RGB1PWM(grn_pwm),.RGB2PWM(red_pwm),.RGBLEDEN('b1),.RGB0(),.RGB1(GRNn),.RGB2(REDn)); | |||||
assign RED = red_pwm; | |||||
assign GRN = grn_pwm; | |||||
endmodule | |||||
// ================================================================== | |||||
// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<< | |||||
// ------------------------------------------------------------------ | |||||
// Copyright (c) 2017 by Lattice Semiconductor Corporation | |||||
// ALL RIGHTS RESERVED | |||||
// ------------------------------------------------------------------ | |||||
// | |||||
// Permission: | |||||
// | |||||
// Lattice SG Pte. Ltd. grants permission to use this code | |||||
// pursuant to the terms of the Lattice Reference Design License Agreement. | |||||
// | |||||
// | |||||
// Disclaimer: | |||||
// | |||||
// This VHDL or Verilog source code is intended as a design reference | |||||
// which illustrates how these types of functions can be implemented. | |||||
// It is the user's responsibility to verify their design for | |||||
// consistency and functionality through the use of formal | |||||
// verification methods. Lattice provides no warranty | |||||
// regarding the use or functionality of this code. | |||||
// | |||||
// -------------------------------------------------------------------- | |||||
// | |||||
// Lattice SG Pte. Lt++++++++++++++++d. | |||||
// 101 Thomson Road, United Square #07-02 | |||||
// Singapore 307591 | |||||
// | |||||
// | |||||
// TEL: 1-800-Lattice (USA and Canada) | |||||
// +65-6631-2000 (Singapore) | |||||
// +1-503-268-8001 (other locations) | |||||
// | |||||
// web: http://www.latticesemi.com/ | |||||
// email: techsupport@latticesemi.com | |||||
// | |||||
// -------------------------------------------------------------------- | |||||
// | |||||
// Project: iCE5UP 5K RGB LED Tutorial | |||||
// File: testbench.v | |||||
// Title: LED PWM control | |||||
// Description: Creates RGB PWM per control inputs | |||||
// | |||||
// | |||||
// -------------------------------------------------------------------- | |||||
// | |||||
//------------------------------------------------------------ | |||||
// Notes: | |||||
// | |||||
// | |||||
//------------------------------------------------------------ | |||||
// Development History: | |||||
// | |||||
// __DATE__ _BY_ _REV_ _DESCRIPTION___________________________ | |||||
// 04/05/17 RK 1.0 Initial tutorial design for Lattice Radiant | |||||
// | |||||
//------------------------------------------------------------ | |||||
// Dependencies: | |||||
// | |||||
// | |||||
// | |||||
//------------------------------------------------------------ | |||||
//------------------------------------------------------------ | |||||
// | |||||
// | |||||
// Testbench | |||||
// | |||||
//------------------------------------------------------------ | |||||
`timescale 1ns/1ps | |||||
module tb; | |||||
//GSR GSR_INST ( .GSR(1)); | |||||
//PUR PUR_INST ( .PUR(1)); | |||||
reg clk12M; | |||||
reg rst; | |||||
reg [9:0]data_input; | |||||
reg data_valid; | |||||
wire RED; | |||||
wire GRN; | |||||
wire alarm; | |||||
led_top dut(.clk12M(clk12M), | |||||
.rst(rst), | |||||
.data_input(data_input), | |||||
.data_valid(data_valid), | |||||
.RED(RED), | |||||
.GRN(GRN), | |||||
.alarm(alarm) | |||||
); | |||||
initial | |||||
begin | |||||
clk12M=1'b0; | |||||
end | |||||
always | |||||
#41.666666 clk12M=~clk12M; //clock generation | |||||
initial | |||||
begin | |||||
rst=1'b1; | |||||
data_input=10'b0000000010; // data for green | |||||
data_valid=1'b0; | |||||
#500000 | |||||
rst=1'b0; | |||||
#500000 | |||||
data_valid = 1'b1; | |||||
#500000 | |||||
data_valid = 1'b0; | |||||
#500000 | |||||
rst=1'b1; | |||||
#500000 | |||||
rst=1'b0; | |||||
data_valid=1'b1; | |||||
data_input=10'b1000000001; // data for yellow | |||||
#500000 | |||||
data_valid=1'b0; | |||||
data_input = 10'b1100000001; //data for red | |||||
#500000 | |||||
data_valid = 1'b1; | |||||
#500000 | |||||
data_input=10'b1000000001; // data for yellow | |||||
#500000 | |||||
rst=1'b1; | |||||
#500000 | |||||
$stop; | |||||
end | |||||
initial | |||||
begin | |||||
$monitor("time=%t,rst=%d,",$time,rst); | |||||
end | |||||
endmodule |
// ================================================================== | |||||
// >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<< | |||||
// ------------------------------------------------------------------ | |||||
// Copyright (c) 2017 by Lattice Semiconductor Corporation | |||||
// ALL RIGHTS RESERVED | |||||
// ------------------------------------------------------------------ | |||||
// | |||||
// Permission: | |||||
// | |||||
// Lattice SG Pte. Ltd. grants permission to use this code | |||||
// pursuant to the terms of the Lattice Reference Design License Agreement. | |||||
// | |||||
// | |||||
// Disclaimer: | |||||
// | |||||
// This VHDL or Verilog source code is intended as a design reference | |||||
// which illustrates how these types of functions can be implemented. | |||||
// It is the user's responsibility to verify their design for | |||||
// consistency and functionality through the use of formal | |||||
// verification methods. Lattice provides no warranty | |||||
// regarding the use or functionality of this code. | |||||
// | |||||
// -------------------------------------------------------------------- | |||||
// | |||||
// Lattice SG Pte. Lt++++++++++++++++d. | |||||
// 101 Thomson Road, United Square #07-02 | |||||
// Singapore 307591 | |||||
// | |||||
// | |||||
// TEL: 1-800-Lattice (USA and Canada) | |||||
// +65-6631-2000 (Singapore) | |||||
// +1-503-268-8001 (other locations) | |||||
// | |||||
// web: http://www.latticesemi.com/ | |||||
// email: techsupport@latticesemi.com | |||||
// | |||||
// -------------------------------------------------------------------- | |||||
// | |||||
// Project: iCE5UP 5K RGB LED Tutorial | |||||
// File: testbench.v | |||||
// Title: LED PWM control | |||||
// Description: Creates RGB PWM per control inputs | |||||
// | |||||
// | |||||
// -------------------------------------------------------------------- | |||||
// | |||||
//------------------------------------------------------------ | |||||
// Notes: | |||||
// | |||||
// | |||||
//------------------------------------------------------------ | |||||
// Development History: | |||||
// | |||||
// __DATE__ _BY_ _REV_ _DESCRIPTION___________________________ | |||||
// 04/05/17 RK 1.0 Initial tutorial design for Lattice Radiant | |||||
// | |||||
//------------------------------------------------------------ | |||||
// Dependencies: | |||||
// | |||||
// | |||||
// | |||||
//------------------------------------------------------------ | |||||
//------------------------------------------------------------ | |||||
// | |||||
// | |||||
// Testbench | |||||
// | |||||
//------------------------------------------------------------ | |||||
class Rst_rnd; | |||||
rand bit [1:0] data; | |||||
constraint Rst_rnd | |||||
{ | |||||
data dist {0:=70,1 :=30}; | |||||
} | |||||
endclass | |||||
class Data_valid_rnd; | |||||
rand bit [1:0] data; | |||||
constraint Data_valid_data | |||||
{ | |||||
data dist {0:=10,1 :=90}; | |||||
} | |||||
endclass | |||||
class Data_input_rnd; | |||||
rand bit [7:0] data; | |||||
endclass | |||||
`timescale 1ns/1ps | |||||
// inputs and outputs | |||||
module tb; | |||||
reg clk12M; | |||||
reg rst; | |||||
reg [7:0]data_input; | |||||
reg data_valid; | |||||
wire RED; | |||||
wire GRN; | |||||
wire alarm; | |||||
//random | |||||
Rst_rnd rst_rnd = new(); | |||||
Data_valid_rnd data_valid_rnd = new(); | |||||
Data_input_rnd data_input_rnd = new(); | |||||
// connect module | |||||
led_top dut(.clk12M(clk12M), | |||||
.rst(rst), | |||||
.data_input(data_input), | |||||
.data_valid(data_valid), | |||||
.RED(RED), | |||||
.GRN(GRN), | |||||
.alarm(alarm) | |||||
); | |||||
//clock | |||||
initial | |||||
begin | |||||
clk12M=1'b0; | |||||
end | |||||
always | |||||
#41.666666 clk12M=~clk12M; //clock generation | |||||
int cycles = 0; | |||||
//random test | |||||
initial begin | |||||
repeat (50) begin | |||||
#50000 | |||||
cycles =cycles+1; | |||||
rst_rnd.randomize(); | |||||
data_input_rnd.randomize(); | |||||
data_valid_rnd.randomize(); | |||||
rst = rst_rnd.data; | |||||
data_input = data_input_rnd.data; | |||||
data_valid = data_valid_rnd.data; | |||||
// assertions | |||||
// assert that reset resets | |||||
assert property ( @(posedge clk12M) (##1 rst) |=> !alarm); | |||||
// assert color green | |||||
assert property(@(posedge clk12M) disable iff (rst | !data_valid| alarm) ((data_input < 100) |=> ##4 (!RED && GRN)); | |||||
//assert color yellow | |||||
assert property(@(posedge clk12M) disable iff (rst | !data_valid| alarm) ((data_input >= 100) && (data_input <= 168))|=> ##4 (RED && GRN)); | |||||
//assert color red + alarm | |||||
assert property(@(posedge clk12M) disable iff (rst | !data_valid) (data_input > 168) |=> ##4 (RED && !GRN && alarm)); | |||||
$monitor("time=%t,cycle%d, rst=%d, data_input=%d, data_valid = %d, RED=%d, GRN=%d, alarm=%d",$time,cycles,rst,data_input, data_valid, RED, GRN, alarm); | |||||
end | |||||
$stop; | |||||
end | |||||
endmodule |