mirror of
https://github.com/pConst/basic_verilog.git
synced 2025-01-14 06:42:54 +08:00
90 lines
2.1 KiB
Systemverilog
90 lines
2.1 KiB
Systemverilog
//------------------------------------------------------------------------------
|
|
// pwm_modulator.sv
|
|
// Konstantin Pavlov, pavlovconst@gmail.com
|
|
//------------------------------------------------------------------------------
|
|
|
|
// INFO ------------------------------------------------------------------------
|
|
// Pulse width modulation (PWM) generator module
|
|
//
|
|
// - expecting 8-bit control signal input by default
|
|
// - system clock is 100 MHz by default
|
|
// - PWM clock is 1.5KHz by default
|
|
//
|
|
// - see also pdm_modulator.sv for pulse density modulation generator
|
|
|
|
|
|
/* --- INSTANTIATION TEMPLATE BEGIN ---
|
|
|
|
pwm_modulator #(
|
|
.PWM_PERIOD_DIV( 16 ) // 100MHz/2^16= ~1.526 KHz
|
|
.MOD_WIDTH( 8 ) // from 0 to 255
|
|
) pwm1 (
|
|
.clk( clk ),
|
|
.nrst( nrst ),
|
|
|
|
.control( ),
|
|
.pwm_out( ),
|
|
|
|
.start_strobe( ),
|
|
.busy( )
|
|
);
|
|
|
|
--- INSTANTIATION TEMPLATE END ---*/
|
|
|
|
module pwm_modulator #( parameter
|
|
CLK_HZ = 100_000_000,
|
|
PWM_PERIOD_DIV = 16, // must be > MOD_WIDTH
|
|
PWM_PERIOD_HZ = CLK_HZ / (2**PWM_PERIOD_DIV),
|
|
|
|
MOD_WIDTH = 8 // modulation bitness
|
|
)(
|
|
input clk, // system clock
|
|
input nrst, // negative reset
|
|
|
|
input [MOD_WIDTH-1:0] mod_setpoint, // modulation setpoint
|
|
output pwm_out, // active HIGH output
|
|
|
|
// status outputs
|
|
output start_strobe, // period start strobe
|
|
output busy // busy output
|
|
);
|
|
|
|
|
|
// period generator
|
|
logic [31:0] div_clk;
|
|
clk_divider #(
|
|
.WIDTH( 32 )
|
|
) cd1 (
|
|
.clk( clk ),
|
|
.nrst( nrst ),
|
|
.ena( 1'b1 ),
|
|
.out( div_clk[31:0] )
|
|
);
|
|
|
|
|
|
// optional setpoint inversion
|
|
logic [MOD_WIDTH-1:0] mod_setpoint_inv;
|
|
assign mod_setpoint_inv[MOD_WIDTH-1:0] = {MOD_WIDTH{1'b1}} - mod_setpoint[MOD_WIDTH-1:0];
|
|
|
|
|
|
// pulse generator
|
|
pulse_gen #(
|
|
.CNTR_WIDTH( MOD_WIDTH+1 )
|
|
) pg1 (
|
|
.clk( div_clk[(PWM_PERIOD_DIV-1)-MOD_WIDTH] ),
|
|
.nrst( nrst ),
|
|
|
|
.start( 1'b1 ),
|
|
.cntr_max( {1'b0, {MOD_WIDTH{1'b1}} } ),
|
|
.cntr_low( {1'b0, mod_setpoint_inv[MOD_WIDTH-1:0] } ),
|
|
|
|
.pulse_out( pwm_out ),
|
|
|
|
.start_strobe( start_strobe ),
|
|
.busy( busy )
|
|
);
|
|
|
|
|
|
endmodule
|
|
|