1
0
mirror of https://github.com/pConst/basic_verilog.git synced 2025-01-14 06:42:54 +08:00
basic_verilog/pdm_modulator.sv
2020-05-06 03:52:20 +03:00

85 lines
1.9 KiB
Systemverilog

//------------------------------------------------------------------------------
// pdm_modulator.sv
// Konstantin Pavlov, pavlovconst@gmail.com
//------------------------------------------------------------------------------
// INFO ------------------------------------------------------------------------
// Pulse density modulation (PDM) generator module
//
// - expecting 8-bit control signal input by default
// - system clock is 100 MHz by default
//
// - see also pwm_modulator.sv for pulse width modulation generator
/* --- INSTANTIATION TEMPLATE BEGIN ---
pdm_modulator #(
.PDM_PERIOD_DIV( 9 )
.MOD_WIDTH( 8 ) // from 0 to 255
) pdm1 (
.clk( clk ),
.nrst( nrst ),
.control( ),
.pdm_out( ),
.start_strobe( ),
.busy( )
);
--- INSTANTIATION TEMPLATE END ---*/
module pdm_modulator #( parameter
CLK_HZ = 100_000_000,
PDM_PERIOD_DIV = 16, // must be > MOD_WIDTH
PDM_MIN_PERIOD_HZ = CLK_HZ / (2**PDM_PERIOD_DIV) * (0+2), // two PDM clock cycles
PDM_MAX_PERIOD_HZ = CLK_HZ / (2**PDM_PERIOD_DIV) * (256+2),
MOD_WIDTH = 8 // modulation bitness
)(
input clk, // system clock
input nrst, // negative reset
input [MOD_WIDTH-1:0] mod_setpoint, // modulation setpoint
output pdm_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] )
);
// pulse generator
pulse_gen #(
.CNTR_WIDTH( MOD_WIDTH+1 )
) pg1 (
.clk( div_clk[(PDM_PERIOD_DIV-1)-MOD_WIDTH] ),
.nrst( nrst ),
.start( 1'b1 ),
.cntr_max( mod_setpoint[MOD_WIDTH-1:0]+2 ),
.cntr_low( 1 ),
.pulse_out( pdm_out ),
.start_strobe( start_strobe ),
.busy( busy )
);
endmodule