mirror of
https://github.com/pConst/basic_verilog.git
synced 2025-01-14 06:42:54 +08:00
131 lines
3.3 KiB
Systemverilog
131 lines
3.3 KiB
Systemverilog
|
//--------------------------------------------------------------------------------
|
||
|
// pulse_gen.sv
|
||
|
// Konstantin Pavlov, pavlovconst@gmail.com
|
||
|
//--------------------------------------------------------------------------------
|
||
|
|
||
|
// INFO --------------------------------------------------------------------------------
|
||
|
// Pulse generator module
|
||
|
// generates one or many pulses of given wigth
|
||
|
// low_wdth[] and high_wdth[] must NOT be 0
|
||
|
|
||
|
// CAUTION:
|
||
|
// - low_wdth[], high_wdth[] and rpt inputs are NOT buffered, so could be changed
|
||
|
// interactively while pulse_gen is already performing
|
||
|
// This could be beneficial for implementing PWM-like genetators with
|
||
|
// variating parameters
|
||
|
|
||
|
|
||
|
/* --- INSTANTIATION TEMPLATE BEGIN ---
|
||
|
|
||
|
pulse_gen #(
|
||
|
.CNTR_WIDTH( 32 )
|
||
|
) pg1 (
|
||
|
.clk( clk ),
|
||
|
.nrst( nrst ),
|
||
|
.low_width( 2 ),
|
||
|
.high_width( 2 ),
|
||
|
.rpt( 1'b0 ),
|
||
|
.start( 1'b1 ),
|
||
|
.busy( ),
|
||
|
.out( )
|
||
|
);
|
||
|
|
||
|
--- INSTANTIATION TEMPLATE END ---*/
|
||
|
|
||
|
module pulse_gen #( parameter
|
||
|
CNTR_WIDTH = 32
|
||
|
)(
|
||
|
|
||
|
input clk,
|
||
|
input nrst,
|
||
|
|
||
|
input [CNTR_WIDTH-1:0] low_width,
|
||
|
input [CNTR_WIDTH-1:0] high_width,
|
||
|
input rpt,
|
||
|
|
||
|
input start, // only first front matters
|
||
|
output busy,
|
||
|
output logic out = 1'b0
|
||
|
);
|
||
|
|
||
|
logic [CNTR_WIDTH-1:0] cnt_low = '0;
|
||
|
logic [CNTR_WIDTH-1:0] cnt_high = '0;
|
||
|
|
||
|
enum logic [1:0] {IDLE,LOW,HIGH} gen_state;
|
||
|
|
||
|
always_ff @(posedge clk) begin
|
||
|
if( ~nrst ) begin
|
||
|
out = 1'b0;
|
||
|
|
||
|
gen_state[1:0] <= IDLE;
|
||
|
|
||
|
cnt_low[CNTR_WIDTH-1:0] <= '0;
|
||
|
cnt_high[CNTR_WIDTH-1:0] <= '0;
|
||
|
end else begin
|
||
|
|
||
|
case( gen_state[1:0] )
|
||
|
IDLE: begin
|
||
|
if( start ) begin
|
||
|
out <= 1'b0;
|
||
|
// latching first pulse widths here
|
||
|
if( low_width[CNTR_WIDTH-1:0] != '0) begin
|
||
|
cnt_low[CNTR_WIDTH-1:0] <= low_width[CNTR_WIDTH-1:0] - 1'b1;
|
||
|
end else begin
|
||
|
cnt_low[CNTR_WIDTH-1:0] <= '0;
|
||
|
end
|
||
|
if( high_width[CNTR_WIDTH-1:0] != '0) begin
|
||
|
cnt_high[CNTR_WIDTH-1:0] <= high_width[CNTR_WIDTH-1:0] - 1'b1;
|
||
|
end else begin
|
||
|
cnt_high[31:0] <= '0;
|
||
|
end
|
||
|
gen_state[1:0] <= LOW;
|
||
|
end
|
||
|
end // IDLE
|
||
|
|
||
|
LOW: begin
|
||
|
if( cnt_low[CNTR_WIDTH-1:0] != 0 ) begin
|
||
|
out <= 1'b0;
|
||
|
cnt_low[CNTR_WIDTH-1:0] <= cnt_low[CNTR_WIDTH-1:0] - 1'b1;
|
||
|
end else begin
|
||
|
out <= 1'b1;
|
||
|
gen_state[1:0] <= HIGH;
|
||
|
end
|
||
|
end // LOW
|
||
|
|
||
|
HIGH: begin
|
||
|
if( cnt_high[CNTR_WIDTH-1:0] != 0 ) begin
|
||
|
out <= 1'b1;
|
||
|
cnt_high[CNTR_WIDTH-1:0] <= cnt_high[CNTR_WIDTH-1:0] - 1'b1;
|
||
|
end else begin
|
||
|
out <= 1'b0;
|
||
|
if( rpt ) begin
|
||
|
// latching repetitive pulse widths here
|
||
|
if( low_width[CNTR_WIDTH-1:0] != '0) begin
|
||
|
cnt_low[CNTR_WIDTH-1:0] <= low_width[CNTR_WIDTH-1:0] - 1'b1;
|
||
|
end else begin
|
||
|
cnt_low[CNTR_WIDTH-1:0] <= '0;
|
||
|
end
|
||
|
if( high_width[CNTR_WIDTH-1:0] != '0) begin
|
||
|
cnt_high[CNTR_WIDTH-1:0] <= high_width[CNTR_WIDTH-1:0] - 1'b1;
|
||
|
end else begin
|
||
|
cnt_high[CNTR_WIDTH-1:0] <= '0;
|
||
|
end
|
||
|
gen_state[1:0] <= LOW;
|
||
|
end else begin
|
||
|
gen_state[1:0] <= IDLE;
|
||
|
end
|
||
|
end
|
||
|
end // HIGH
|
||
|
|
||
|
default: gen_state[1:0] <= IDLE;
|
||
|
endcase // gen_state
|
||
|
|
||
|
end // nrst
|
||
|
end
|
||
|
|
||
|
assign busy = (gen_state[1:0] != IDLE);
|
||
|
|
||
|
|
||
|
endmodule
|
||
|
|