Signal scope

This commit is contained in:
2026-03-05 15:06:09 +01:00
parent 8cccea85e0
commit b0582e63bc
7 changed files with 387 additions and 3 deletions

View File

@@ -0,0 +1,141 @@
`include "clog2.vh"
module signal_scope_q15 #(
parameter depth = 2**12,
parameter chain = 1
)(
input wire i_clk,
input wire i_rst,
input wire [15:0] i_signal_a,
input wire i_signal_valid_a,
input wire [15:0] i_signal_b,
input wire i_signal_valid_b,
input wire [15:0] i_signal_c,
input wire i_signal_valid_c,
input wire [15:0] i_signal_d,
input wire i_signal_valid_d
);
localparam aw = `CLOG2(depth);
localparam [aw-1:0] depth_last = depth-1;
(* ram_style = "block" *) reg [16*4-1:0] mem[depth-1:0];
reg [aw-1:0] counter;
reg count_enable;
reg rearm_prev;
reg [15:0] signal_a;
reg [15:0] signal_b;
reg [15:0] signal_c;
reg [15:0] signal_d;
reg signal_a_pending;
reg signal_b_pending;
reg signal_c_pending;
reg signal_d_pending;
wire [31:0] wb_adr;
wire [31:0] wb_dat;
wire [3:0] wb_sel;
wire wb_we;
wire wb_cyc;
wire wb_stb;
reg [31:0] wb_rdt;
reg wb_ack;
wire rearm_cmd;
wire [aw-1:0] wb_mem_idx = wb_adr[aw+2:3];
jtag_wb_bridge #(
.chain(chain),
.byte_aligned(0)
) jtag_scope_bridge (
.i_clk(i_clk),
.i_rst(i_rst),
.o_wb_adr(wb_adr),
.o_wb_dat(wb_dat),
.o_wb_sel(wb_sel),
.o_wb_we(wb_we),
.o_wb_cyc(wb_cyc),
.o_wb_stb(wb_stb),
.i_wb_rdt(wb_rdt),
.i_wb_ack(wb_ack),
.o_cmd_reset(rearm_cmd)
);
always @(posedge i_clk) begin
if(i_rst) begin
counter <= {aw{1'b0}};
count_enable <= 1'b0;
rearm_prev <= 1'b0;
wb_ack <= 1'b0;
wb_rdt <= 32'b0;
signal_a <= 0;
signal_b <= 0;
signal_c <= 0;
signal_d <= 0;
signal_a_pending <= 1'b0;
signal_b_pending <= 1'b0;
signal_c_pending <= 1'b0;
signal_d_pending <= 1'b0;
end else begin
// Sample signals
if(i_signal_valid_a) begin
signal_a <= i_signal_a;
signal_a_pending <= 1'b1;
end
if(i_signal_valid_b) begin
signal_b <= i_signal_b;
signal_b_pending <= 1'b1;
end
if(i_signal_valid_c) begin
signal_c <= i_signal_c;
signal_c_pending <= 1'b1;
end
if(i_signal_valid_d) begin
signal_d <= i_signal_d;
signal_d_pending <= 1'b1;
end
// Rearm on rising edge of reset command from JTAG bridge.
rearm_prev <= rearm_cmd;
if(rearm_cmd && !rearm_prev) begin
counter <= {aw{1'b0}};
count_enable <= 1'b1;
signal_a_pending <= 1'b0;
signal_b_pending <= 1'b0;
signal_c_pending <= 1'b0;
signal_d_pending <= 1'b0;
end
// Write one full 4-channel frame at a time for maximum BRAM throughput.
if(count_enable && signal_a_pending && signal_b_pending && signal_c_pending && signal_d_pending) begin
if(counter <= depth_last) begin
mem[counter] <= {signal_a, signal_b, signal_c, signal_d};
counter <= counter + 3'd1;
if(counter == depth_last)
count_enable <= 1'b0;
end else begin
count_enable <= 1'b0;
end
signal_a_pending <= 1'b0;
signal_b_pending <= 1'b0;
signal_c_pending <= 1'b0;
signal_d_pending <= 1'b0;
end
// Simple WB slave response for JTAG reads (32-bit = 2x16-bit samples).
wb_ack <= wb_cyc & wb_stb & !wb_ack;
if(wb_cyc & wb_stb & !wb_ack) begin
if(wb_we) begin
wb_rdt <= 32'b0;
end else if(wb_mem_idx <= depth_last) begin
// A single frame is 64-bit: {a, b, c, d}. WB reads low/high 32-bit halves.
wb_rdt <= wb_adr[2] ? mem[wb_mem_idx][63:32] : mem[wb_mem_idx][31:0];
end else begin
wb_rdt <= 32'b0;
end
end
end
end
endmodule