| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- `timescale 1ns/1ps
- module pwm_control_demo_tb;
- reg clk;
- reg reset_n;
- reg signed [7:0] cmd;
- reg enable;
- reg fault;
- wire signed [7:0] limited_cmd;
- wire direction;
- wire [6:0] duty;
- wire pwm_out;
- integer errors;
- integer high_count;
- integer i;
- pwm_control_demo dut (
- .clk(clk),
- .reset_n(reset_n),
- .cmd(cmd),
- .enable(enable),
- .fault(fault),
- .limited_cmd(limited_cmd),
- .direction(direction),
- .duty(duty),
- .pwm_out(pwm_out)
- );
- // 100 MHz simulation clock.
- // Frequency itself is not important for this demo;
- // PWM duty ratio is what we verify.
- initial clk = 0;
- always #5 clk = ~clk;
- task check_control;
- input signed [7:0] test_cmd;
- input signed [7:0] expected_limit;
- input expected_direction;
- input [6:0] expected_duty;
- begin
- cmd = test_cmd;
- #1;
- if (limited_cmd !== expected_limit) begin
- $display("FAIL limiter: cmd=%0d expected=%0d actual=%0d",
- test_cmd, expected_limit, limited_cmd);
- errors = errors + 1;
- end else begin
- $display("PASS limiter: cmd=%0d -> %0d",
- test_cmd, limited_cmd);
- end
- if (direction !== expected_direction) begin
- $display("FAIL direction: cmd=%0d expected=%0d actual=%0d",
- test_cmd, expected_direction, direction);
- errors = errors + 1;
- end else begin
- $display("PASS direction: cmd=%0d direction=%0d",
- test_cmd, direction);
- end
- if (duty !== expected_duty) begin
- $display("FAIL duty: cmd=%0d expected=%0d actual=%0d",
- test_cmd, expected_duty, duty);
- errors = errors + 1;
- end else begin
- $display("PASS duty: cmd=%0d duty=%0d%%",
- test_cmd, duty);
- end
- end
- endtask
- task check_pwm;
- input [6:0] expected_percent;
- begin
- high_count = 0;
- // Measure exactly one complete 100-clock PWM period.
- for (i = 0; i < 100; i = i + 1) begin
- @(negedge clk);
- if (pwm_out)
- high_count = high_count + 1;
- end
- if (high_count !== expected_percent) begin
- $display("FAIL PWM: expected=%0d%% measured=%0d%%",
- expected_percent, high_count);
- errors = errors + 1;
- end else begin
- $display("PASS PWM: expected=%0d%% measured=%0d%%",
- expected_percent, high_count);
- end
- end
- endtask
- initial begin
- errors = 0;
- reset_n = 0;
- cmd = 0;
- enable = 0;
- fault = 0;
- repeat (3) @(posedge clk);
- reset_n = 1;
- $display("");
- $display("========== PWM CONTROL TEST ==========");
- // Normal forward command
- enable = 1;
- fault = 0;
- check_control(25, 25, 0, 25);
- check_pwm(25);
- // Another normal command
- check_control(50, 50, 0, 50);
- check_pwm(50);
- // Upper limiter
- check_control(95, 90, 0, 90);
- check_pwm(90);
- // Reverse command
- check_control(-50, -50, 1, 50);
- check_pwm(50);
- // Lower limiter
- check_control(-120, -90, 1, 90);
- check_pwm(90);
- // Zero command
- check_control(0, 0, 0, 0);
- check_pwm(0);
- // Disable interlock
- cmd = 50;
- enable = 0;
- fault = 0;
- #1;
- check_pwm(0);
- $display("PASS enable=0 forces PWM OFF");
- // Fault interlock
- enable = 1;
- fault = 1;
- #1;
- check_pwm(0);
- $display("PASS fault=1 forces PWM OFF");
- $display("");
- if (errors == 0) begin
- $display("======================================");
- $display("ALL TESTS PASSED");
- $display("======================================");
- $finish;
- end else begin
- $display("======================================");
- $display("TEST FAILED: %0d error(s)", errors);
- $display("======================================");
- $fatal(1);
- end
- end
- endmodule
|