基于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
相关产品推荐
相关产品推荐

