You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于VHDL的PWM控制LED仿真问题求助

Help with VHDL LED Brightness Controller Simulation in ModelSim

我最近写了一套用于控制LED亮度的VHDL代码,包括主控制器和对应的测试平台,但在Altera ModelSim里做仿真的时候碰到了技术问题,折腾了半天都没搞定。有没有大佬能帮我编译一下这些代码,再提供对应的仿真结果呀?真的非常感谢!

测试平台代码(Testbench Code)

这个测试平台会每隔5秒切换一组命令,覆盖了4种频率(0.2Hz、0.5Hz、1Hz、2Hz)和4种占空比(10%、30%、60%、85%)的组合:

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.all; 
use IEEE.STD_LOGIC_UNSIGNED.ALL; 

entity main_testbench is 
end main_testbench; 

architecture behavior of main_testbench is 
component led_controller is 
Port ( 
    clk, reset: in std_logic; -- system clock is assumed 10KHz 
    in_word: in std_logic_vector(7 downto 0); -- LS 4 bits - frequency & MS 4 bits - duty-cycle 
    LEDs: out std_logic_vector(3 downto 0)
); 
end component; 

signal clk, reset: std_logic := '0'; 
signal in_word: std_logic_vector(7 downto 0) := "00010001"; -- 0.2 Hz, 10% duty cycle 
signal LEDs: std_logic_vector(3 downto 0) := "0000"; 

type in_word_commands is array (0 to 15) of std_logic_vector(7 downto 0); 
signal in_words: in_word_commands := (
    "00010001", "00010010", "00010100", "00011000", -- 10% duty cycle with 0.2Hz, 0.5Hz, 1Hz, 2Hz 
    "00100001", "00100010", "00100100", "00101000", -- 30% duty cycle with 0.2Hz, 0.5Hz, 1Hz, 2Hz 
    "01000001", "01000010", "01000100", "01001000", -- 60% duty cycle with 0.2Hz, 0.5Hz, 1Hz, 2Hz 
    "10000001", "10000010", "10000100", "10001000"  -- 85% duty cycle with 0.2Hz, 0.5Hz, 1Hz, 2Hz 
); 
signal command_num : integer := 0; 

begin 
dut: led_controller port map (clk, reset, in_word, LEDs); 

clk <= not clk after 50 us; -- 0.1ms/2 = 50us (10KHz clock)
command_num <= command_num + 1 after 5000 ms; -- 5000ms = 5s, switch command every 5 seconds
in_word <= in_words(command_num); 

end behavior; 

LED控制器代码(LED Controller Code)

控制器通过输入的in_word配置LED的闪烁频率和占空比,低4位控制频率,高4位控制占空比:

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.all; 

entity led_controller is 
Port ( 
    clk, reset: in std_logic; 
    in_word: in std_logic_vector(7 downto 0); 
    LEDs: out std_logic_vector(3 downto 0)
); 
end led_controller; 

architecture behavior of led_controller is 
--------------------- signals --------------------- 
type freq is array (0 to 3) of integer range 0 to 50000; 
signal frq: freq := (25000, 10000, 5000, 2500); --对应0.2Hz,0.5Hz,1Hz,2Hz(基于10KHz时钟)
signal led_freq_count: integer range 0 to 50000 := frq(0); 

type d is array (0 to 3) of integer range 0 to 100; 
signal duty: d := (10, 30, 60, 85); --占空比百分比
signal duty_cycle: integer range 0 to 100 := duty(0); 

signal LED_switch, new_command: std_logic := '0'; 

begin 
--------- clock process / sync reset configuration --------------- 
process (clk) 
variable duty_counter: integer range 0 to 100 := 100; 
variable freq_counter: integer range 0 to 50000 := led_freq_count; 
begin 
    if rising_edge(clk) then 
        ------- if reset was high or new in_word were arrived -------- 
        if reset = '1' or new_command = '1' then 
            LEDs <= "0000"; 
            duty_counter := 100; 
            freq_counter := led_freq_count; 
            new_command <= '0'; 
        else 
            ------- blinking process -------- 
            if freq_counter = 0 then 
                freq_counter := led_freq_count; 
                LED_switch <= not LED_switch; 
            end if; 
            freq_counter := freq_counter - 1; 

            if duty_counter = 0 then 
                duty_counter := 100; 
            end if; 
            duty_counter := duty_counter - 1; 

            ------ output assignment ------- 
            if LED_switch = '1' and duty_counter < duty_cycle then 
                LEDs <= "1111"; 
            else 
                LEDs <= "0000"; 
            end if; 
        end if; 
    end if; 
end process; 

--------- input process--------------- 
process (in_word) 
begin 
    case in_word(3 downto 0) is 
        when "0001" => led_freq_count <= frq(0); 
        when "0010" => led_freq_count <= frq(1); 
        when "0100" => led_freq_count <= frq(2); 
        when "1000" => led_freq_count <= frq(3); 
        when others => led_freq_count <= frq(0); 
    end case; 

    case in_word(7 downto 4) is 
        when "0001" => duty_cycle <= duty(0); 
        when "0010" => duty_cycle <= duty(1); 
        when "0100" => duty_cycle <= duty(2); 
        when "1000" => duty_cycle <= duty(3); 
        when others => duty_cycle <= duty(0); 
    end case; 
    new_command <= '1'; 
end process; 

end behavior; 

内容的提问来源于stack exchange,提问作者Abdullah Al Mamun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:36:03