2023-03-11 18:04:53 +00:00
|
|
|
`default_nettype none
|
|
|
|
|
|
|
|
module genSaw
|
|
|
|
( input var i_clk48
|
|
|
|
, input var i_rst48_n
|
|
|
|
, input var i_pause
|
2023-05-16 21:11:17 +00:00
|
|
|
, input var [23:0] i_targetf
|
2023-05-18 11:35:39 +00:00
|
|
|
, input var [ 7:0] i_wave
|
2023-05-16 21:11:17 +00:00
|
|
|
, output var [15:0] o_sample
|
|
|
|
, output var o_pulse
|
2023-03-11 18:04:53 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
logic [8:0] clk_div;
|
2023-05-16 21:11:17 +00:00
|
|
|
always_ff @(posedge i_clk48) // Count half 48kHz cycle
|
|
|
|
if (!i_rst48_n) clk_div <= 0;
|
|
|
|
else if (clk_div == 9'd499) clk_div <= 0;
|
|
|
|
else clk_div <= clk_div + 1;
|
2023-03-11 18:04:53 +00:00
|
|
|
|
|
|
|
logic clk_48k;
|
2023-05-16 21:11:17 +00:00
|
|
|
always_ff @(posedge i_clk48) // Generate 48kHz clock
|
|
|
|
if (!i_rst48_n) clk_48k <= 0;
|
|
|
|
else if (clk_div == 9'd0) clk_48k <= ~clk_48k;
|
2023-03-11 18:04:53 +00:00
|
|
|
|
|
|
|
logic clk_48k_past;
|
2023-05-16 21:11:17 +00:00
|
|
|
always_ff @(posedge i_clk48) // Track rising / falling edge of 48kHz clock
|
|
|
|
clk_48k_past <= clk_48k;
|
2023-03-11 18:04:53 +00:00
|
|
|
|
2023-05-18 11:01:56 +00:00
|
|
|
always_comb o_pulse = clk_48k && !clk_48k_past; // Detect rising edge of 48kHz clock
|
2023-03-11 18:04:53 +00:00
|
|
|
|
2023-05-16 21:11:17 +00:00
|
|
|
logic [23:0] int_saw_step;
|
2023-05-18 11:01:56 +00:00
|
|
|
always_comb int_saw_step = (24'd699 * i_targetf); // Sawtooth step calc from input target freq
|
2023-03-11 18:04:53 +00:00
|
|
|
|
2023-05-16 21:11:17 +00:00
|
|
|
logic [15:0] saw_step;
|
2023-05-18 11:01:56 +00:00
|
|
|
always_comb saw_step = {1'b0, int_saw_step[23:9]}; // Shift step right correctly (2^9)
|
2023-03-11 18:04:53 +00:00
|
|
|
|
2023-05-18 11:35:39 +00:00
|
|
|
logic [15:0] saw;
|
|
|
|
always_ff @(posedge clk_48k) // Generate new saw sample on rising edge of 48kHz clock
|
|
|
|
if (!i_rst48_n) saw <= '0;
|
|
|
|
else if (!i_pause) saw <= saw + saw_step; // Add saw_step if not paused (48kHz)
|
|
|
|
|
|
|
|
logic [15:0] square;
|
2023-05-18 15:19:53 +00:00
|
|
|
always_comb square = {~saw[15], {15{saw[15]}}}; // Square wave is MSB of saw
|
2023-05-18 11:35:39 +00:00
|
|
|
|
|
|
|
logic [15:0] triangle;
|
2023-05-18 11:42:09 +00:00
|
|
|
always_comb triangle = saw[15] ? {~saw[14:0], 1'b1} : {saw[14:0], 1'b0}; // Triangle wave calc
|
2023-05-18 11:35:39 +00:00
|
|
|
|
|
|
|
logic [15:0] sine;
|
2023-05-28 15:07:23 +00:00
|
|
|
saw2sin m_saw2sin // Instantiate saw2sin module
|
|
|
|
( .i_saw(saw)
|
|
|
|
, .o_sin(sine)
|
|
|
|
);
|
2023-05-18 11:35:39 +00:00
|
|
|
|
|
|
|
always_comb // Select output waveform
|
|
|
|
case (i_wave[1:0])
|
|
|
|
2'd0: o_sample = saw;
|
|
|
|
2'd1: o_sample = square;
|
|
|
|
2'd2: o_sample = triangle;
|
|
|
|
2'd3: o_sample = sine;
|
|
|
|
endcase
|
2023-03-11 18:04:53 +00:00
|
|
|
|
|
|
|
endmodule
|