pwm на verilog в три строки.

В программном виде можно представить шим модулированный сигнал как импульс поделенный на разрядность самого шим модулятора.

Значит нам надо счетчик, компаратор и несколько регистров. Алгоритм прост, по достижении счетчиком входного значения перевести выход в 0 иначе оставить 1. На Verilog для 8 битного ШИМ-а это выглядит следующим образом. Разрядность регулируется исключительно размером входного сигнала, и разрядностью счетчика.
module pwm(in,clk,out);
input[7:0] in;
input clk;
output out;
reg[7:0] counter;
reg out;
always@(posedge clk)
begin
if(counter<=in)
out <=1'b1;
else
out <=1'b0;
counter<=counter+8'b1;
end
endmodule
И ясное дело скрин из квартуса

- +1
- 11 октября 2012, 12:09
- letni
кстати. вариант реализации ШИМ для источника тока. самая мелкая альтера, в которую это влезет, будет явно дешевле даже одного компаратора. а клок можно и с контроллера подать.
на самом деле у меня просто кроме альтер «самых дешевых» больше ничего не валяется. Хотя для того применения куда он надо (как мигалка с плавным затуханием и возгаранием) можно было обойтись одним транзистором генератором синуса + повторитель на оу. Кстати, случаем ни кто не имеет идей по поводу СНЧ (!) генератора синуса, потому что простой генератор с фазовым сдвигом отказался работать, а использовать лампочки в мостах вина мне религия не позволяет.
Этот код вполне понятен и прозрачен, а вот другой код с сайта fpga4fan.com я не сильно понимаю
если можно обьясните разницу
module PWM(clk, PWM_in, PWM_out);
input clk;
input [7:0] PWM_in;
output PWM_out;
reg [8:0] PWM_accumulator;
always @(posedge clk) PWM_accumulator <= PWM_accumulator[7:0] + PWM_in;
assign PWM_out = PWM_accumulator[8];
endmodule
если можно обьясните разницу
- mishgan_zp
- 11 октября 2012, 14:03
- ↓
это не шим, это сигма-дельта. только они забыли еще PWM_out к аккумулятору как младший бит добавить, если подать код 255 то «1» на выходе будет не всё время, а будет иногда в 0 дергаться. но это мелочи.
и имхо сигма-дельта модуляция гораздо лучше чем широтно-импульсная, да и всего в одну строчку, а не в три :)
вот то же самое, только они с вычитанием красивее обошлись просто откинув старший разряд.
при коде 128, например, на выходе ШИМа будет меандр с частотой clk/256, а тут всего clk/2, а высокую частоту гораздо легче потом отфильтровывать.
да и ресурсов съест почти столько же, (по триггерам) разве что сумматор может немного посложнее выходит.
и имхо сигма-дельта модуляция гораздо лучше чем широтно-импульсная, да и всего в одну строчку, а не в три :)
вот то же самое, только они с вычитанием красивее обошлись просто откинув старший разряд.
module SigmaDeltaModulator(in, clk, out);
parameter WIDTH = 8;
input[WIDTH-1:0] in;
input clk;
output out;
reg[WIDTH:0] acc = 0;
assign out = acc[WIDTH];
always @(posedge clk) acc <= acc + in + out - (out << WIDTH);
endmodule
при коде 128, например, на выходе ШИМа будет меандр с частотой clk/256, а тут всего clk/2, а высокую частоту гораздо легче потом отфильтровывать.
да и ресурсов съест почти столько же, (по триггерам) разве что сумматор может немного посложнее выходит.
Начал изучение ПЛИСок, и взял тут ваш пример ШИМа себе просимулировать. Использую Icarus Verilog для сборки и GTKVawe для симуляции. Возник вопрос, нужно ли дать начальное значение переменной counter = 0? Т.к. у меня при симуляции всегда на выходе out всегда 0 (т.е. всегда работает ветка когда counter больше in) пока не задал начальное значение этой переменной
Комментарии (10)
RSS свернуть / развернуть