Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

LED Breahing DE0 nano

can you help me what the meaning of this short program

it's from demos de0 nano i want to convert it to vhdl

" pwm_width <= pwm_width[5:0]+ pwm_adj;

if(counter[26])

begin

pwm_adj <= counter[25:20];

end

else begin

pwm_adj <= ~ counter[25:20];

end "

this the full demos program

// ============================================================================

// Copyright (c) 2011 by Terasic Technologies Inc.

// ============================================================================

//

// Permission:

//

// Terasic grants permission to use and modify this code for use

// in synthesis for all Terasic Development Boards and Altera Development

// Kits made by Terasic. Other use of this code, including the selling

// ,duplication, or modification of any portion is strictly prohibited.

//

// Disclaimer:

//

// This VHDL/Verilog or C/C++ 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. Terasic provides no warranty regarding the use

// or functionality of this code.

//

// ============================================================================

//

// Terasic Technologies Inc

// 356 Fu-Shin E. Rd Sec. 1. JhuBei City,

// HsinChu County, Taiwan

// 302

//

// web: http://www.terasic.com/

// email: support@terasic.com

//

// ============================================================================

// Major Functions/Design Description:

//

// Please refer to DE0_Nano_User_manual.pdf in DE0_Nano system CD.

//

// ============================================================================

// Revision History:

// ============================================================================

// Ver.: |Author: |Mod. Date: |Changes Made:

// V1.0 |EricChen |02/01/2011 |

// ============================================================================

//=======================================================

// This code is generated by Terasic System Builder

//=======================================================

module DE0_NANO(

//////////// CLOCK //////////

CLOCK_50,

//////////// LED //////////

LED,

//////////// KEY //////////

KEY,

//////////// SW //////////

SW,

//////////// SDRAM //////////

DRAM_ADDR,

DRAM_BA,

DRAM_CAS_N,

DRAM_CKE,

DRAM_CLK,

DRAM_CS_N,

DRAM_DQ,

DRAM_DQM,

DRAM_RAS_N,

DRAM_WE_N,

//////////// EPCS //////////

EPCS_ASDO,

EPCS_DATA0,

EPCS_DCLK,

EPCS_NCSO,

//////////// Accelerometer and EEPROM //////////

G_SENSOR_CS_N,

G_SENSOR_INT,

I2C_SCLK,

I2C_SDAT,

//////////// ADC //////////

ADC_CS_N,

ADC_SADDR,

ADC_SCLK,

ADC_SDAT,

//////////// 2x13 GPIO Header //////////

GPIO_2,

GPIO_2_IN,

//////////// GPIO_0, GPIO_0 connect to GPIO Default //////////

GPIO_0_D,

GPIO_0_IN,

//////////// GPIO_0, GPIO_1 connect to GPIO Default //////////

GPIO_1_D,

GPIO_1_IN,

);

//=======================================================

// PARAMETER declarations

//=======================================================

//=======================================================

// PORT declarations

//=======================================================

//////////// CLOCK //////////

input CLOCK_50;

//////////// LED //////////

output [7:0] LED;

//////////// KEY //////////

input [1:0] KEY;

//////////// SW //////////

input [3:0] SW;

//////////// SDRAM //////////

output [12:0] DRAM_ADDR;

output [1:0] DRAM_BA;

output DRAM_CAS_N;

output DRAM_CKE;

output DRAM_CLK;

output DRAM_CS_N;

inout [15:0] DRAM_DQ;

output [1:0] DRAM_DQM;

output DRAM_RAS_N;

output DRAM_WE_N;

//////////// EPCS //////////

output EPCS_ASDO;

input EPCS_DATA0;

output EPCS_DCLK;

output EPCS_NCSO;

//////////// Accelerometer and EEPROM //////////

output G_SENSOR_CS_N;

input G_SENSOR_INT;

output I2C_SCLK;

inout I2C_SDAT;

//////////// ADC //////////

output ADC_CS_N;

output ADC_SADDR;

output ADC_SCLK;

input ADC_SDAT;

//////////// 2x13 GPIO Header //////////

inout [12:0] GPIO_2;

input [2:0] GPIO_2_IN;

//////////// GPIO_0, GPIO_0 connect to GPIO Default //////////

inout [33:0] GPIO_0_D;

input [1:0] GPIO_0_IN;

//////////// GPIO_0, GPIO_1 connect to GPIO Default //////////

inout [33:0] GPIO_1_D;

input [1:0] GPIO_1_IN;

//=======================================================

// REG/WIRE declarations

//=======================================================

wire reset_n;

reg [26:0] counter;

reg [5:0] PWM_adj;

reg [6:0] PWM_width;

reg [7:0] LED;

reg [33:0] GPIO_0_D;

//=======================================================

// Structural coding

//=======================================================

assign reset_n = KEY[0];

always @(posedge CLOCK_50 or negedge reset_n)

begin

if(!reset_n)

begin

counter <= 0;

LED[0] <= 0;

GPIO_0_D[2]<= 0;

end

else begin

counter <= counter+1;

PWM_width <= PWM_width[5:0]+ PWM_adj;

if(counter[26])

begin

PWM_adj <= counter[25:20];

end

else begin

PWM_adj <= ~ counter[25:20];

end

LED[0] <= ~PWM_width[6];

LED[1] <= ~PWM_width[6];

LED[2] <= ~PWM_width[6];

LED[3] <= ~PWM_width[6];

LED[4] <= PWM_width[6];

LED[5] <= PWM_width[6];

LED[6] <= PWM_width[6];

LED[7] <= PWM_width[6];

GPIO_0_D[2]<= PWM_width[6];

end

end

endmodule

9 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    What do you want to know exactly?

    The meaning of the lines listed in the beginning or the meaning of the whole demo?

    I can't understand your question, since the operation involved with the listed lines is quite simple, even if you had no knowledge of Verilog syntax.

    On the other hand I think the purpose of the whole code is described by the title of you post: it generates a sort of 'breathing' behaviour in the LEDs, by dimming the brightness through pulse width modulation.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    What do you want to know exactly?

    The meaning of the lines listed in the beginning or the meaning of the whole demo?

    I can't understand your question, since the operation involved with the listed lines is quite simple, even if you had no knowledge of Verilog syntax.

    On the other hand I think the purpose of the whole code is described by the title of you post: it generates a sort of 'breathing' behaviour in the LEDs, by dimming the brightness through pulse width modulation.

    --- Quote End ---

    idon't understand about value in if condition ,PWM_Adj

    1." if(counter[26]) " when condition this active? i don't know value in counter to reach this condition.

    2. "PWM_adj <= counter[25:20]" why just 25:20 ? i'ts that mean value in array counter[20],counter[21],....counter[25][/I][/I].

    3. "pwm_width <= pwm_width[5:0]+ pwm_adj;"

    in reg/wire declarations pwm adj have 6bit dan pwm width have 7bit, why in just 6 bit in pwm width " + " with pwm adj??

    reg [5:0] PWM_adj;

    reg [6:0] PWM_width;

    5.if in vhdl variable counter is defined as std_logic_vector(26 downto 0) right?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    1." if(counter[26]) " when condition this active? i don't know value in counter to reach this condition.

    --- Quote End ---

    counter[26] is the msb of counter vector.

    I guess the process clock runs at 50MHz, then counter[26] continuosly toggles between 1 and 0 at the rate of about 1Hz,

    namely when the 26bit counter overflows

    --- Quote Start ---

    2. "PWM_adj <= counter[25:20]" why just 25:20 ? i'ts that mean value in array counter[20],counter[21],....counter[25][/I][/I].

    --- Quote End ---

    This is simply to obtain a lower increment period. Compared to the full counter, the sub-array counter[25:20] increments every 20ms

    --- Quote Start ---

    3. "pwm_width <= pwm_width[5:0]+ pwm_adj;"

    in reg/wire declarations pwm adj have 6bit dan pwm width have 7bit, why in just 6 bit in pwm width " + " with pwm adj??

    reg [5:0] PWM_adj;

    reg [6:0] PWM_width;

    --- Quote End ---

    I believe this should have been written in a clearer and more correct way:

    PWM_width <= { 1'b0, PWM_width[5:0] } + PWM_adj;"

    Verilog is much more tolerant than VHDL regarding type mismatch. Probably the original syntax generates a warning but can compile anyway.

    --- Quote Start ---

    5.if in vhdl variable counter is defined as std_logic_vector(26 downto 0) right?

    --- Quote End ---

    --- Quote End ---

    Yes.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    counter[26] is the msb of counter vector.

    I guess the process clock runs at 50MHz, then counter[26] continuosly toggles between 1 and 0 at the rate of about 1Hz,

    namely when the 26bit counter overflows

    i still don't understand about msb counter that have 26 bit

    if in vhdl i read when bit array counter[26] high or '1' like example below it's that same like if (counter[26])??

    if(counter="100000000000000000000000000")then

    how could i make this to vhdl

    This is simply to obtain a lower increment period. Compared to the full counter, the sub-array counter[25:20] increments every 20ms

    sub array counter increament every 20 ms if i use counter[26:0] how about the in increment?

    I believe this should have been written in a clearer and more correct way:

    PWM_width <= { 1'b0, PWM_width[5:0] } + PWM_adj;"

    it's 1'b0 = 1 bit in biner the value = 0 and the pwm 6bit logic vector it's pwm width convert to 1 bit or std logic?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    if in vhdl i read when bit array counter[26] high or '1' like example below it's that same like if (counter[26])??

    if(counter="100000000000000000000000000")then

    --- Quote End ---

    No. This condition is true if bit 26 is high AND all the others are low.

    The vhdl equivalent is simply:

    if counter(26) ='1' then

    --- Quote Start ---

    sub array counter increament every 20 ms if i use counter[26:0] how about the in increment?

    --- Quote End ---

    I can't understand your question

    --- Quote Start ---

    I believe this should have been written in a clearer and more correct way:

    PWM_width <= { 1'b0, PWM_width[5:0] } + PWM_adj;"

    it's 1'b0 = 1 bit in biner the value = 0 and the pwm 6bit logic vector it's pwm width convert to 1 bit or std logic?

    --- Quote End ---

    This is Verilog syntax. { 1'b0, PWM_width[5:0] } builds a 7 bit vector by concatenating the single bit value=0 and the lower 6bits of PWM_width.

    std logic is vhdl specific and doesn't apply to verilog.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    example pwm_adj<= counter + 1 // that mean the increment value is "1" every clock rising edge or high

    PWM_adj <= counter[25:20];[/I][/I][/I][/I] how i know the increment value?

    for make easy to understand how could make it in vhdl

    PWM_width <= PWM_width[5:0]+ PWM_adj;

    and

    PWM_adj <= counter[25:20];

    is it like this "pwm_width <= pwm_width[5]+ pwm_adj"?

    how about make "PWM_adj <= counter[25:20];" to vhdl [/I][/I]

    i think verilog it's quite diffucult to understand than vhdl

    [/I][/I]
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    example pwm_adj<= counter + 1 // that mean the increment value is "1" every clock rising edge or high

    pwm_adj <= counter[25:20];how i know the increment value?

    --- Quote End ---

    There's no increment involved.

    This simply assign to PWM_adj the same value as bits 25 to 20 of counter array

    --- Quote Start ---

    for make easy to understand how could make it in vhdl

    PWM_width <= PWM_width[5:0]+ PWM_adj;

    and

    PWM_adj <= counter[25:20];

    --- Quote End ---

    I'm not versed in VHDL. I rather use verilog.

    I think you should use something like:

    PWM_width <= ('0' & PWM_width(5 downto 0)) + ('0' & PWM_adj);

    PWM_adj <= counter(25 downto 20);

    --- Quote Start ---

    is it like this "pwm_width <= pwm_width[5]+ pwm_adj"?

    --- Quote End ---

    No. pwm_width[5] only adds a 1bit value, by taking the 5th bit from pwm_width.

    --- Quote Start ---

    i think verilog it's quite diffucult to understand than vhdl

    --- Quote End ---

    People usually thinks the opposite way.

    Verilog is simpler, especially for users with a C programming background.

    vhdl is more powerful but syntax is somehow very different from what sw programmers are used to.

    Moreover vhdl requires a strong type consistency, where verilog has looser rules.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    thank you mr cris72

    it's working well

    this the vhdl code

    library ieee;

    USE ieee.std_logic_1164.all;

    use ieee.std_logic_arith.all;

    use ieee.std_logic_unsigned.all;

    ENTITY DE0_NANO IS

    PORT( LED : out std_logic_vector(7 downto 0);

    KEY : in std_logic_vector(1 downto 0);

    CLOCK_50 : in std_logic

    );

    END DE0_NANO;

    ARCHITECTURE behavioral OF DE0_NANO IS

    signal reset_n: std_logic;

    signal counter: std_logic_vector(26 downto 0);

    signal PWM_adj: std_logic_vector(5 downto 0);

    Signal PWM_width : std_logic_vector (6 downto 0);

    begin

    reset_n <= KEY(0);

    process(CLOCK_50)is

    begin

    if(CLOCK_50'event and CLOCK_50 ='1') then

    if (reset_n='0') then

    counter <= "000000000000000000000000000";

    LED(0) <= '0';

    else

    counter <= counter+'1';

    PWM_width <= ('0' & PWM_width(5 downto 0)) + ('0' & PWM_adj);

    if(counter(26)='1')then

    PWM_adj <= counter(25 downto 20);

    else

    PWM_adj <= not counter(25 downto 20);

    end if;

    LED(0) <= not PWM_width(6);

    LED(1) <= not PWM_width(6);

    LED(2) <= not PWM_width(6);

    LED(3) <= not PWM_width(6);

    LED(4) <= PWM_width(6);

    LED(5) <= PWM_width(6);

    LED(6) <= PWM_width(6);

    LED(7) <= PWM_width(6);

    end if;

    end if;

    end process;

    END behavioral;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    is this program make led dimming from 0 to 100 % brightness ?

    PWM_width <= ('0' & PWM_width(5 downto 0)) + ('0' & PWM_adj); -- 0-100% --

    if(counter(26)='1')then

    PWM_adj <= counter(25 downto 20); -- 0-100% --

    else

    PWM_adj <= not counter(25 downto 20);

    end if;

    i try to change range in pwm_adj from 25 downto 20 i think that mean dimming from 0 -100% brightness

    then i change it to 23 down to 20 then it's dimming about 0-50% brightness

    if i want to want led dimming just only 50% (not from 0 to 50% )what should i do with the counter ??

    PWM_width <= ('0' & PWM_width(5 downto 0)) + ('0' & PWM_adj); -- 0-50% --

    if(counter(26)='1')then

    PWM_adj <= counter(23 downto 20); -- 0-50% --

    else

    PWM_adj <= counter(23 downto 20);

    end if;

    LED(0) <= PWM_width(6);

    LED(1) <= PWM_width(6);

    LED(2) <= PWM_width(6);

    LED(3) <= PWM_width(6);