@@ -0,0 +1,184 @@ | |||
// ================================================================== | |||
// >>>>>>>>>>>>>>>>>>>>>>> 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 |
@@ -0,0 +1,46 @@ | |||
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 | |||
@@ -0,0 +1,141 @@ | |||
// ================================================================== | |||
// >>>>>>>>>>>>>>>>>>>>>>> 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 |
@@ -0,0 +1,155 @@ | |||
// ================================================================== | |||
// >>>>>>>>>>>>>>>>>>>>>>> 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 |