Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions rtl/avs96/avs96_step.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Wave 45 lane QQ, S-196 + S-197 + S-200 milestone, anchor phi^2+phi^-2=3,
// DOI 10.5281/zenodo.19227877. 96 voltage steps, 6250 uV bin width.

module avs96_dac_bank (
input logic clk,
input logic rst_n,
input logic [6:0] step_sel, // 7-bit selector, valid range 0..95
output logic [6:0] dac_out, // selected step (clamped if out-of-range)
output logic step_valid
);
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
dac_out <= 7'd0;
step_valid <= 1'b0;
end else if (step_sel < 7'd96) begin
dac_out <= step_sel;
step_valid <= 1'b1;
end else begin
dac_out <= 7'd0;
step_valid <= 1'b0;
end
end
endmodule

module vdd_step_controller (
input logic clk,
input logic rst_n,
input logic [6:0] target_step, // dopamine occupancy bin
input logic step_request,
output logic [6:0] current_step,
output logic transition_done
);
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
current_step <= 7'd0;
transition_done <= 1'b0;
end else if (step_request) begin
if (current_step < target_step) begin
current_step <= current_step + 7'd1;
transition_done <= 1'b0;
end else if (current_step > target_step) begin
current_step <= current_step - 7'd1;
transition_done <= 1'b0;
end else begin
transition_done <= 1'b1;
end
end
end
endmodule

module avs96_step_top (
input logic clk,
input logic rst_n,
input logic [6:0] step_sel,
input logic [6:0] target_step,
input logic step_request,
output logic [6:0] dac_out,
output logic step_valid,
output logic [6:0] current_step,
output logic transition_done
);

avs96_dac_bank u_dac_bank (
.clk (clk),
.rst_n (rst_n),
.step_sel (step_sel),
.dac_out (dac_out),
.step_valid (step_valid)
);

vdd_step_controller u_vdd_ctrl (
.clk (clk),
.rst_n (rst_n),
.target_step (target_step),
.step_request (step_request),
.current_step (current_step),
.transition_done (transition_done)
);

endmodule
129 changes: 129 additions & 0 deletions rtl/avs96/avs96_step_tb.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Wave 45 lane QQ testbench for avs96_step_top
// 7 test cases: TB1-TB7

`timescale 1ns/1ps

module avs96_step_tb;

logic clk;
logic rst_n;
logic [6:0] step_sel;
logic [6:0] target_step;
logic step_request;
logic [6:0] dac_out;
logic step_valid;
logic [6:0] current_step;
logic transition_done;

avs96_step_top dut (
.clk (clk),
.rst_n (rst_n),
.step_sel (step_sel),
.target_step (target_step),
.step_request (step_request),
.dac_out (dac_out),
.step_valid (step_valid),
.current_step (current_step),
.transition_done (transition_done)
);

initial clk = 0;
always #5 clk = ~clk;

task tick(input int n);
repeat (n) @(posedge clk);
#1;
endtask

int pass_count;
int fail_count;

task check(input string name, input logic got, input logic exp);
if (got === exp) begin
$display("PASS %s", name);
pass_count++;
end else begin
$display("FAIL %s: got=%0b exp=%0b", name, got, exp);
fail_count++;
end
endtask

task check7(input string name, input logic [6:0] got, input logic [6:0] exp);
if (got === exp) begin
$display("PASS %s", name);
pass_count++;
end else begin
$display("FAIL %s: got=%0d exp=%0d", name, got, exp);
fail_count++;
end
endtask

initial begin
pass_count = 0;
fail_count = 0;
rst_n = 1'b0;
step_sel = 7'd0;
target_step = 7'd0;
step_request = 1'b0;

// TB1: reset asserted -> dac_out=0, step_valid=0
tick(2);
check7("TB1_dac_out", dac_out, 7'd0);
check("TB1_step_valid", step_valid, 1'b0);

// Release reset
rst_n = 1'b1;
tick(1);

// TB2: step_sel=0 -> dac_out=0, step_valid=1
step_sel = 7'd0;
tick(1);
check7("TB2_dac_out", dac_out, 7'd0);
check("TB2_step_valid", step_valid, 1'b1);

// TB3: step_sel=95 -> dac_out=95, step_valid=1
step_sel = 7'd95;
tick(1);
check7("TB3_dac_out", dac_out, 7'd95);
check("TB3_step_valid", step_valid, 1'b1);

// TB4: step_sel=96 -> dac_out=0, step_valid=0 (out of range)
step_sel = 7'd96;
tick(1);
check7("TB4_dac_out", dac_out, 7'd0);
check("TB4_step_valid", step_valid, 1'b0);

// TB5: vdd_step_controller ramp 0->3 over 3 clocks
rst_n = 1'b0;
target_step = 7'd0;
step_request = 1'b0;
tick(2);
rst_n = 1'b1;
tick(1);
target_step = 7'd3;
step_request = 1'b1;
tick(1); check7("TB5_step1", current_step, 7'd1);
tick(1); check7("TB5_step2", current_step, 7'd2);
tick(1); check7("TB5_step3", current_step, 7'd3);

// TB6: vdd_step_controller ramp 3->0 over 3 clocks
target_step = 7'd0;
tick(1); check7("TB6_step1", current_step, 7'd2);
tick(1); check7("TB6_step2", current_step, 7'd1);
tick(1); check7("TB6_step3", current_step, 7'd0);

// TB7: transition_done asserted when current_step == target_step
target_step = 7'd0;
tick(1);
check("TB7_transition_done", transition_done, 1'b1);

$display("Results: %0d passed, %0d failed", pass_count, fail_count);
if (fail_count == 0)
$display("ALL TESTS PASSED");
else
$display("SOME TESTS FAILED");

$finish;
end

endmodule
Loading