78 lines
2.9 KiB
Verilog
78 lines
2.9 KiB
Verilog
// Captures one burst of sampled bits into block RAM for offline analysis. Keeps every
|
|
// decimation-th sample and packs it MSB first into bytes: one bit per sample from
|
|
// source A, or in pair mode two bits per sample (A then B) so both sources are recorded
|
|
// at the same instants.
|
|
module raw_capture #(
|
|
parameter ADDR_WIDTH = 15 // 2^15 bytes = 256 Kbit per burst
|
|
) (
|
|
input wire clk,
|
|
input wire reset,
|
|
input wire bit_a,
|
|
input wire bit_b,
|
|
input wire pair_mode,
|
|
input wire [15:0] decimation, // 0 and 1 both mean every sample
|
|
input wire start,
|
|
output reg busy,
|
|
output reg done,
|
|
input wire [ADDR_WIDTH-1:0] read_addr,
|
|
output reg [7:0] read_data
|
|
);
|
|
|
|
reg [7:0] buffer [0:(1 << ADDR_WIDTH) - 1];
|
|
|
|
reg [15:0] sample_count;
|
|
reg [3:0] bit_count;
|
|
reg [7:0] partial_byte;
|
|
reg [ADDR_WIDTH-1:0] next_addr;
|
|
reg write_enable;
|
|
reg [ADDR_WIDTH-1:0] write_addr;
|
|
reg [7:0] write_data;
|
|
|
|
wire keep_sample = (sample_count == 16'd0);
|
|
wire count_wraps = (decimation <= 16'd1) || (sample_count == decimation - 16'd1);
|
|
|
|
wire [7:0] shifted = pair_mode ? {partial_byte[5:0], bit_a, bit_b} : {partial_byte[6:0], bit_a};
|
|
wire [3:0] new_count = bit_count + (pair_mode ? 4'd2 : 4'd1);
|
|
|
|
always @(posedge clk) begin
|
|
write_enable <= 1'b0;
|
|
if (reset) begin
|
|
busy <= 1'b0;
|
|
done <= 1'b0;
|
|
end else if (start) begin
|
|
busy <= 1'b1;
|
|
done <= 1'b0;
|
|
sample_count <= 16'd0;
|
|
bit_count <= 4'd0;
|
|
next_addr <= {ADDR_WIDTH{1'b0}};
|
|
end else if (busy) begin
|
|
sample_count <= count_wraps ? 16'd0 : sample_count + 16'd1;
|
|
if (keep_sample) begin
|
|
partial_byte <= shifted;
|
|
if (new_count == 4'd8) begin
|
|
bit_count <= 4'd0;
|
|
write_enable <= 1'b1;
|
|
write_addr <= next_addr;
|
|
write_data <= shifted;
|
|
next_addr <= next_addr + 1'b1;
|
|
if (&next_addr) begin
|
|
busy <= 1'b0;
|
|
done <= 1'b1;
|
|
end
|
|
end else begin
|
|
bit_count <= new_count;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
// Two read registers: the first becomes the RAM's address register, the second its output
|
|
// register, which keeps the wide block-RAM output multiplexer off the SPI timing path.
|
|
reg [7:0] read_data_ram;
|
|
always @(posedge clk) begin
|
|
if (write_enable) buffer[write_addr] <= write_data;
|
|
read_data_ram <= buffer[read_addr];
|
|
read_data <= read_data_ram;
|
|
end
|
|
|
|
endmodule
|