evgoi 0 10 декабря, 2013 Опубликовано 10 декабря, 2013 · Жалоба Доброго всем времени суток!... Прошу помощи, мне требовалось сделать ШИМ с настройкой периода и частоты, при этом сейчас появилась необходимость добавить к уже имеющемуся коду настроечный вход типа "ПИЛЫ". Для 1 должна быть пила, а для 0 обратная пила. Я даже теоретически не представляю себе как его сделать. Помогите пожалуйста дописать к уже имеющемуся коду данную настройку. Исходный код выложу ниже. Спасибо. LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; ENTITY pwm IS GENERIC( sys_clk : INTEGER := 50_000_000; pwm_freq : INTEGER := 100_000; bits_resolution : INTEGER := 8; phases : INTEGER := 1); PORT( clk : IN STD_LOGIC; reset_n : IN STD_LOGIC; ena : IN STD_LOGIC; duty : IN STD_LOGIC_VECTOR(bits_resolution-1 DOWNTO 0); pwm_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0); pwm_n_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0)); END pwm; ARCHITECTURE logic OF pwm IS CONSTANT period : INTEGER := sys_clk/pwm_freq; TYPE counters IS ARRAY (0 TO phases-1) OF INTEGER RANGE 0 TO period - 1; SIGNAL count : counters := (OTHERS => 0); SIGNAL half_duty : INTEGER RANGE 0 TO period/2 := 0; BEGIN PROCESS(clk, reset_n) BEGIN IF(reset_n = '0') THEN count <= (OTHERS => 0); pwm_out <= (OTHERS => '0'); pwm_n_out <= (OTHERS => '0'); ELSIF(clk'EVENT AND clk = '1') THEN IF(ena = '1') THEN half_duty <= conv_integer(duty)*period/(2**bits_resolution)/2; END IF; FOR i IN 0 to phases-1 LOOP IF(count(0) = period - 1 - i*period/phases) THEN count(i) <= 0; ELSE count(i) <= count(i) + 1; END IF; END LOOP; FOR i IN 0 to phases-1 LOOP IF(count(i) = half_duty) THEN pwm_out(i) <= '0'; pwm_n_out(i) <= '1'; ELSIF(count(i) = period - half_duty) THEN pwm_out(i) <= '1'; pwm_n_out(i) <= '0'; END IF; END LOOP; END IF; END PROCESS; END logic; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 10 декабря, 2013 Опубликовано 10 декабря, 2013 · Жалоба не надо трогать этот модуль надо сделать модуль обертку, который будет подавать увеличивающийся или уменьшающийся счетчик на вход этого модуля. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
evgoi 0 10 декабря, 2013 Опубликовано 10 декабря, 2013 · Жалоба не надо трогать этот модуль надо сделать модуль обертку, который будет подавать увеличивающийся или уменьшающийся счетчик на вход этого модуля. Спасибо!...А как это сделать не подскажите? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 10 декабря, 2013 Опубликовано 10 декабря, 2013 · Жалоба давно на VHDL не писал... так что пас... я чет даже не помню как в нем модули объявляются... попробовал но ничего хорошего не выйдет... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 11 декабря, 2013 Опубликовано 11 декабря, 2013 · Жалоба Спасибо!...А как это сделать не подскажите? поробуйте "поиграться" с ... count(i) <= count(i) + 1; ... + поменять на - и посмотрите что будет... для управления можно написать что-то в таком духе: ... if sel = "1" then count(i) <= count(i) + 1; else count(i) <= count(i) - 1; end if; ... и не забудьте добавить sel в декларацию сигналов/порта выхода Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
doc17 0 11 декабря, 2013 Опубликовано 11 декабря, 2013 · Жалоба Спасибо!...А как это сделать не подскажите? Примерно так, если я верно понял, что нужно: LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; ENTITY pwm_sawtooth IS GENERIC( sys_clk : INTEGER := 50_000_000; pwm_freq : INTEGER := 100_000; bits_resolution : INTEGER := 8; phases : INTEGER := 1 ); PORT( clk : IN STD_LOGIC; reset_n : IN STD_LOGIC; ena : IN STD_LOGIC; pwm_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0); pwm_n_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0); direction : IN STD_LOGIC -- set sawtooth direction: 0 - rising, 1 - falling ); END pwm_sawtooth; ARCHITECTURE logic OF pwm_sawtooth IS -- Components used in the design COMPONENT pwm GENERIC( sys_clk : INTEGER := 50_000_000; pwm_freq : INTEGER := 100_000; bits_resolution : INTEGER := 8; phases : INTEGER := 1 ); PORT( clk : IN STD_LOGIC; reset_n : IN STD_LOGIC; ena : IN STD_LOGIC; duty : IN STD_LOGIC_VECTOR(bits_resolution-1 DOWNTO 0); pwm_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0); pwm_n_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0) ); END COMPONENT; -- Entity variables SIGNAL duty: STD_LOGIC_VECTOR(bits_resolution-1 DOWNTO 0); BEGIN -- PWM module connection pwm_cmp: pwm GENERIC MAP( sys_clk => sys_clk, pwm_freq => pwm_freq, bits_resolution => bits_resolution, phases => phases ) PORT MAP( clk => clk, reset_n => reset_n, ena => ena, duty => duty, pwm_out => pwm_out, pwm_n_out => pwm_n_out ); -- Sawtooth counter PROCESS(clk, reset_n) BEGIN IF(reset_n = '0') THEN duty <= (OTHERS => '0'); ELSIF(rising_edge(clk)) THEN IF(direction = '0') THEN duty <= duty + '1'; ELSE duty <= duty - '1'; END IF; END IF; END PROCESS; END logic; А вот тестбенч (на верилоге для простоты): // Testbench for PWM_SAWTOOTH module module pwm_sawtooth_tb; reg clk, reset_n; wire ena = 1'b1; reg direction; initial begin clk = 1'b0; reset_n = 1'b0; direction = 1'b0; #1 reset_n = 1'b1; #1000 direction = 1'b1; end pwm_sawtooth DUT ( .clk, .reset_n, .ena, //pwm_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0); //pwm_n_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0); .direction ); endmodule // pwm_sawtooth_tb Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 11 декабря, 2013 Опубликовано 11 декабря, 2013 · Жалоба Примерно так, если я верно понял, что нужно: LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; ENTITY pwm_sawtooth IS GENERIC( sys_clk : INTEGER := 50_000_000; pwm_freq : INTEGER := 100_000; bits_resolution : INTEGER := 8; phases : INTEGER := 1 ); PORT( clk : IN STD_LOGIC; reset_n : IN STD_LOGIC; ena : IN STD_LOGIC; pwm_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0); pwm_n_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0); direction : IN STD_LOGIC -- set sawtooth direction: 0 - rising, 1 - falling ); END pwm_sawtooth; ARCHITECTURE logic OF pwm_sawtooth IS -- Components used in the design COMPONENT pwm GENERIC( sys_clk : INTEGER := 50_000_000; pwm_freq : INTEGER := 100_000; bits_resolution : INTEGER := 8; phases : INTEGER := 1 ); PORT( clk : IN STD_LOGIC; reset_n : IN STD_LOGIC; ena : IN STD_LOGIC; duty : IN STD_LOGIC_VECTOR(bits_resolution-1 DOWNTO 0); pwm_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0); pwm_n_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0) ); END COMPONENT; -- Entity variables SIGNAL duty: STD_LOGIC_VECTOR(bits_resolution-1 DOWNTO 0); BEGIN -- PWM module connection pwm_cmp: pwm GENERIC MAP( sys_clk => sys_clk, pwm_freq => pwm_freq, bits_resolution => bits_resolution, phases => phases ) PORT MAP( clk => clk, reset_n => reset_n, ena => ena, duty => duty, pwm_out => pwm_out, pwm_n_out => pwm_n_out ); -- Sawtooth counter PROCESS(clk, reset_n) BEGIN IF(reset_n = '0') THEN duty <= (OTHERS => '0'); ELSIF(rising_edge(clk)) THEN IF(direction = '0') THEN duty <= duty + '1'; ELSE duty <= duty - '1'; END IF; END IF; END PROCESS; END logic; А вот тестбенч (на верилоге для простоты): // Testbench for PWM_SAWTOOTH module module pwm_sawtooth_tb; reg clk, reset_n; wire ena = 1'b1; reg direction; initial begin clk = 1'b0; reset_n = 1'b0; direction = 1'b0; #1 reset_n = 1'b1; #1000 direction = 1'b1; end pwm_sawtooth DUT ( .clk, .reset_n, .ena, //pwm_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0); //pwm_n_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0); .direction ); endmodule // pwm_sawtooth_tb Ваше описание задает изменение длительности ШИМ (соотношение 1 и 0 в периоде) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
evgoi 0 12 декабря, 2013 Опубликовано 12 декабря, 2013 · Жалоба Большое спасибо вам!... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
doc17 0 13 декабря, 2013 Опубликовано 13 декабря, 2013 · Жалоба Ваше описание задает изменение длительности ШИМ (соотношение 1 и 0 в периоде) evgoi ведь того и хотел ? появилась необходимость добавить к уже имеющемуся коду настроечный вход типа "ПИЛЫ". Для 1 должна быть пила, а для 0 обратная пила. Или ... ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться