-
Notifications
You must be signed in to change notification settings - Fork 2
/
pwm.v
120 lines (100 loc) · 3.02 KB
/
pwm.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/* ---------------------------------------------------- *
* Title : General purpose Pulse-Width modulators *
* Project : Verilog Utility Modules *
* ---------------------------------------------------- *
* File : pwm.v *
* Author : Yigit Suoglu *
* Last Edit : 09/10/2021 *
* Licence : CERN-OHL-W *
* ---------------------------------------------------- *
* Description : Generate PWM signals *
* ---------------------------------------------------- */
/*
* modules pmw_* does not hold value_in value stable during operation.
* However implemented algorithm exhibit immunity against changes in
* value_in to a some extent, e.g. after sig_out is low
*/
module pwm_256(clk, rst, value_in, sig_out, sync);
input clk, rst;
input [7:0] value_in;
output reg sig_out;
output sync; //New cycle begins at negedge
reg [7:0] counter;
assign sync = ~|counter;
always @(posedge clk or posedge rst)
begin
if(rst)
begin
counter <= 8'd0;
end
else
begin
counter <= counter + 8'd1;
end
end
always@(posedge clk)
begin // All 1s All 0s New cycle Pulse end
sig_out <= (&value_in) | ((|value_in) & ((~|counter) | ((counter != value_in) & sig_out)));
end
endmodule//8 bit, 256 values
module pwm256(clk, rst, value_in, sig_out);
input clk, rst;
input [7:0] value_in;
output sig_out;
wire sync;
reg [7:0] value_reg;
pwm_256 pwm_core(clk, rst, value_reg, sig_out, sync);
always@(posedge clk or posedge rst)
begin
if(rst)
begin
value_reg <= value_in;
end
else
begin
value_reg <= (sync) ? value_in : value_reg;
end
end
endmodule//8 bit, 256 values
module pwm_per100(clk, rst, value_in, sig_out, sync);
input clk, rst;
input [6:0] value_in;
output reg sig_out;
output sync; //New cycle begins at negedge
reg [6:0] counter;
assign sync = ~|counter;
always @(posedge clk or posedge rst)
begin
if(rst)
begin
counter <= 7'd0;
end
else
begin
counter <= (counter == 7'd99) ? 7'd0 : counter + 7'd1;
end
end
always@(posedge clk)
begin // 100% 0% New cycle Pulse end
sig_out <= (value_in == 7'd100) | ((|value_in) & ((~|counter) | ((counter != value_in) & sig_out)));
end
endmodule//100 values
module pwm100(clk, rst, value_in, sig_out);
input clk, rst;
input [6:0] value_in;
output sig_out;
wire sync;
reg [6:0] value_reg;
pwm_per100 pwm_core(clk, rst, value_reg, sig_out, sync);
always@(posedge clk or posedge rst)
begin
if(rst)
begin
value_reg <= value_in;
end
else
begin
value_reg <= (sync) ? value_in : value_reg;
end
end
endmodule//100 values