diff --git a/Source_Ampel/LED_control.sv b/Source_Ampel/LED_control.sv new file mode 100644 index 0000000..5faf159 --- /dev/null +++ b/Source_Ampel/LED_control.sv @@ -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 \ No newline at end of file diff --git a/Source_Ampel/rgb_led_top.sv b/Source_Ampel/rgb_led_top.sv new file mode 100644 index 0000000..e2bec6d --- /dev/null +++ b/Source_Ampel/rgb_led_top.sv @@ -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 + + + + + + + + + + + + + + diff --git a/Source_Ampel/testbench.sv b/Source_Ampel/testbench.sv new file mode 100644 index 0000000..688df0f --- /dev/null +++ b/Source_Ampel/testbench.sv @@ -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 \ No newline at end of file diff --git a/Source_Ampel/testbench_random.sv b/Source_Ampel/testbench_random.sv new file mode 100644 index 0000000..ba617a1 --- /dev/null +++ b/Source_Ampel/testbench_random.sv @@ -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 \ No newline at end of file