Skip to content

Commit

Permalink
feat: add debug signals to testbench
Browse files Browse the repository at this point in the history
  • Loading branch information
Elizabeth-0 committed Feb 19, 2025
1 parent 635501c commit 9c3fd9c
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 154 deletions.
79 changes: 32 additions & 47 deletions src/tt_um_waves.v
Original file line number Diff line number Diff line change
Expand Up @@ -370,80 +370,54 @@ module i2s_transmitter (
output reg sd // Serial data output
);

reg [3:0] bit_counter; // Counts bits being sent
reg [3:0] bit_counter; // Counts bits being sent (0 to 15)
reg [15:0] shift_reg; // Shift register for transmitting data
reg [7:0] clk_div; // Clock divider for generating `sck`

parameter SCK_DIV = 16; // Adjust this based on your clock frequency
parameter SCK_DIV = 16; // Clock divider for serial clock generation (adjust as needed)

// Main logic
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
// Reset all signals
clk_div <= 0;
sck <= 0;
ws <= 0;
sd <= 0;
bit_counter <= 0;
shift_reg <= 16'd0;
end else if (ena) begin
// Generate I2S Serial Clock (sck) at the correct frequency
// Generate I2S Serial Clock (sck)
if (clk_div == (SCK_DIV - 1)) begin
clk_div <= 0;
sck <= ~sck; // Toggle sck
end else begin
clk_div <= clk_div + 1;
end

// Data Transmission Logic (Shift Register)
if (sck == 0) begin // Shift data on the falling edge of sck
// Data Transmission Logic
if (sck == 0 && clk_div == 0) begin // Align logic to sck falling edge
if (bit_counter == 0) begin
ws <= ~ws; // Toggle word select every 16 bits
shift_reg <= {data, data}; // Duplicate 8-bit data for 16-bit format
shift_reg <= {data, data}; // Load 8-bit data into 16-bit format
end else begin
shift_reg <= shift_reg << 1; // Shift left to send MSB first
shift_reg <= shift_reg << 1; // Shift left to transmit MSB first
end

sd <= shift_reg[15]; // Output MSB first
bit_counter <= (bit_counter == 15) ? 0 : bit_counter + 1;
sd <= shift_reg[15]; // Output MSB on `sd`
bit_counter <= (bit_counter == 15) ? 0 : bit_counter + 1; // Reset or increment counter
end
end else begin
// If not enabled, hold outputs steady
sck <= 0;
ws <= 0;
sd <= 0;
end
end
endmodule



/*module sine_wave_generator (
input wire ena, // Enable signal
input wire clk, // Clock
input wire rst_n, // Active-low reset
input wire [31:0] freq_select, // Frequency selection (32 bits)
output reg [7:0] wave_out // 8-bit sine wave output
);
reg [7:0] counter; // Counter for the sine table index
reg [31:0] clk_div; // Clock divider (32-bit)
reg [7:0] sine_table [0:255]; // Lookup table for sine wave
// Cargar la tabla desde un archivo externo
initial $readmemh("sine_table.mem", sine_table);
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
counter <= 8'd0;
clk_div <= 32'd0;
wave_out <= 8'd0;
end else if (ena) begin
if (clk_div >= freq_select - 1) begin
clk_div <= 32'd0;
counter <= (counter == 8'd255) ? 8'd0 : counter + 1; // Asegurar wrap-around
wave_out <= sine_table[counter]; // Leer la ROM
end else begin
clk_div <= clk_div + 1;
end
end
end
endmodule*/


module square_wave_generator (
input wire ena, // Enable signal
input wire clk, // Clock
Expand Down Expand Up @@ -573,17 +547,25 @@ endmodule


module triangular_wave_generator (
input wire ena, // Enable signal
input wire clk, // Clock
input wire rst_n, // Active-low reset
input wire ena, // Enable signal
input wire clk, // Clock
input wire rst_n, // Active-low reset
input wire [31:0] freq_select, // Frequency selection (32-bit)
output reg [7:0] wave_out // 8-bit triangular wave output
output reg [7:0] wave_out, // 8-bit triangular wave output
output wire [3:0] debug // Debugging signals (optional)
);

// Internal registers
reg [7:0] counter; // 8-bit counter for wave generation
reg direction; // 1: counting up, 0: counting down
reg [31:0] clk_div; // 32-bit clock divider
reg [31:0] debug_counter; // Debug counter for signal changes

// Assign debug signals to external pins (optional)
assign debug[0] = wave_clk; // Clock toggle
assign debug[1] = ena; // Enable signal
assign debug[2] = direction; // Current direction
assign debug[3] = wave_out[7]; // MSB of output waveform

// Main logic
always @(posedge clk or negedge rst_n) begin
Expand All @@ -593,9 +575,11 @@ module triangular_wave_generator (
direction <= 1'b1; // Start counting up
clk_div <= 32'd0;
wave_out <= 8'd0;
debug_counter <= 32'd0; // Reset debug counter
end else if (ena) begin
// Increment the clock divider
// Increment the clock divider and debug counter
clk_div <= clk_div + 1;
debug_counter <= debug_counter + 1;

// Check if clock divider has reached the frequency threshold
if (clk_div >= freq_select - 1) begin
Expand Down Expand Up @@ -626,6 +610,7 @@ endmodule




module encoder #(
parameter WIDTH = 8,
parameter INCREMENT = 1'b1
Expand Down
202 changes: 95 additions & 107 deletions test/tb.v
Original file line number Diff line number Diff line change
@@ -1,116 +1,104 @@
`default_nettype none
`timescale 1ns / 1ps

/* Testbench for tt_um_waves */
`default_nettype none

module tb;

// Dump signals to a VCD file for waveform analysis
initial begin
$dumpfile("tb.vcd");
$dumpvars(0, tb);
end

// Clock generation (25 MHz -> 40 ns period)
reg clk = 0;
always #20 clk = ~clk; // Toggle every 20 ns -> 25 MHz

// Reset and enable signals
reg rst_n = 0;
reg ena = 0;

// Inputs and outputs
reg [7:0] ui_in = 0;
reg [7:0] uio_in = 0;
wire [7:0] uo_out;
wire [7:0] uio_out;
wire [7:0] uio_oe;

// I2S Signals
wire i2s_sck = uo_out[0];
wire i2s_ws = uo_out[1];
wire i2s_sd = uo_out[2];

// Instantiate the module under test
tt_um_waves dut (
.ui_in (ui_in),
.uo_out (uo_out),
.uio_in (uio_in),
.uio_out(uio_out),
.uio_oe (uio_oe),
.ena (ena),
.clk (clk),
.rst_n (rst_n)
);

// Reset and enable sequence
initial begin
#200;
rst_n = 1; // Release reset
#50;
ena = 1; // Enable I2S transmitter and waveform generation

// Transmit arbitrary data for testing
#200;
ui_in = 8'h41;

// Run simulation for a sufficient duration
#500000;
$finish;
end

// UART transmission simulation
task uart_send(input [7:0] data);
integer i;
begin
ui_in[0] = 0; // Start bit
#(25_000_000 / 9600);

for (i = 0; i < 8; i = i + 1) begin
ui_in[0] = (data >> i) & 1;
#(25_000_000 / 9600); // 9600 baud bit time
end

ui_in[0] = 1; // Stop bit
#(25_000_000 / 9600);
end
endtask

// Test sequence for UART commands & I2S validation
reg [3:0] j;
initial begin
#300;

// Test wave selection
uart_send(8'h54); // 'T' for Triangle wave
#1000;
$display("Triangle Wave Selected - I2S SD: %b", i2s_sd);

uart_send(8'h53); // 'S' for Sawtooth wave
#1000;
$display("Sawtooth Wave Selected - I2S SD: %b", i2s_sd);

uart_send(8'h51); // 'Q' for Square wave
#1000;
$display("Square Wave Selected - I2S SD: %b", i2s_sd);

// Test frequency selection
for (j = 0; j < 10; j = j + 1) begin
uart_send(8'h30 + j);
#1000;
$display("Freq %d Selected - I2S SCK: %b, WS: %b, SD: %b", j, i2s_sck, i2s_ws, i2s_sd);
// Simulation clock and reset
reg clk = 0;
always #20 clk = ~clk; // 25 MHz clock (40 ns period)

reg rst_n = 0; // Active-low reset
reg ena = 0; // Enable signal

// Inputs and outputs for the DUT
reg [7:0] ui_in = 0; // UART input
reg [7:0] uio_in = 0; // User IO (used for ADSR control)
wire [7:0] uo_out; // Output (I2S signals)
wire [7:0] uio_out; // IO output (unused in this design)
wire [7:0] uio_oe; // IO output enable (unused in this design)

// I2S signals for verification
wire i2s_sck = uo_out[0];
wire i2s_ws = uo_out[1];
wire i2s_sd = uo_out[2];

// Instantiate the DUT
tt_um_waves dut (
.ui_in (ui_in),
.uo_out (uo_out),
.uio_in (uio_in),
.uio_out(uio_out),
.uio_oe (uio_oe),
.ena (ena),
.clk (clk),
.rst_n (rst_n)
);

// VCD file for waveform analysis
initial begin
$dumpfile("tb.vcd");
$dumpvars(0, tb);
end

// White Noise Test
uart_send(8'h4E); // Enable White Noise
#1000;
$display("White Noise Enabled - I2S SD: %b", i2s_sd);

uart_send(8'h46); // Disable White Noise
#1000;
$display("White Noise Disabled - I2S SD: %b", i2s_sd);
// Reset and initialization sequence
initial begin
#100; // Wait for simulation to settle
rst_n = 1; // Release reset
#50;
ena = 1; // Enable the design

// Send test commands via UART
uart_send(8'h54); // Select triangle wave
#1000;
uart_send(8'h53); // Select sawtooth wave
#1000;
uart_send(8'h51); // Select square wave
#1000;

// Test frequency selection via UART
uart_send(8'h30); // Set frequency 0
#1000;
uart_send(8'h31); // Set frequency 1
#1000;

// Enable white noise
uart_send(8'h4E); // Enable white noise
#1000;
uart_send(8'h46); // Disable white noise
#1000;

// Simulate ADSR control
uio_in = 8'b00000011; // Example ADSR configuration
#10000;

// Finish simulation
$finish;
end

$finish;
end
// UART transmission task
task uart_send(input [7:0] data);
integer i;
begin
// Start bit
ui_in[0] = 0;
#1041660; // Simulate 9600 baud (1/9600s = ~1041660ns at 25 MHz clock)

// Send 8 data bits (LSB first)
for (i = 0; i < 8; i = i + 1) begin
ui_in[0] = data[i];
#1041660; // 9600 baud bit time
end

// Stop bit
ui_in[0] = 1;
#1041660;
end
endtask

// Monitor key signals
initial begin
$monitor("Time: %0dns | wave_select: %h | freq_select: %h | i2s_sck: %b | i2s_ws: %b | i2s_sd: %b",
$time, dut.uart_rx_inst.wave_select, dut.uart_rx_inst.freq_select, i2s_sck, i2s_ws, i2s_sd);
end

endmodule

0 comments on commit 9c3fd9c

Please sign in to comment.