Skip to content

Commit

Permalink
noise buffer bringup in hardware partly successful, todo: reimplement…
Browse files Browse the repository at this point in the history
… timestamping
  • Loading branch information
reed-foster committed Oct 2, 2023
1 parent 7df0dc5 commit c725162
Show file tree
Hide file tree
Showing 10 changed files with 405 additions and 24 deletions.
6 changes: 3 additions & 3 deletions dds_test.srcs/sources_1/new/axis_x2.sv
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ module axis_x2 #(
Axis_If.Master_Simple data_out
);

logic [SAMPLE_WIDTH-1:0] data_in_reg [PARALLEL_SAMPLES]; // 1Q15
logic [2*SAMPLE_WIDTH-1:0] product [PARALLEL_SAMPLES]; // 2Q30
logic [SAMPLE_WIDTH-1:0] product_d [PARALLEL_SAMPLES]; // 2Q14
logic signed [SAMPLE_WIDTH-1:0] data_in_reg [PARALLEL_SAMPLES]; // 1Q15
logic signed [2*SAMPLE_WIDTH-1:0] product [PARALLEL_SAMPLES]; // 2Q30
logic signed [SAMPLE_WIDTH-1:0] product_d [PARALLEL_SAMPLES]; // 2Q14
logic [3:0] valid_d;

always_ff @(posedge clk) begin
Expand Down
26 changes: 18 additions & 8 deletions dds_test.srcs/sources_1/new/dac_prescaler.sv
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,22 @@ module dac_prescaler #(
input wire clk, reset,
Axis_If.Master_Simple data_out,
Axis_If.Slave_Simple data_in,
input [17:0] scale_factor
Axis_If.Slave_Simple scale_factor // 2Q16
);

logic [SAMPLE_WIDTH-1:0] data_in_reg [PARALLEL_SAMPLES]; // 1Q15
logic [17:0] scale_factor_reg; // 2Q16
logic [33:0] product [PARALLEL_SAMPLES]; // 3Q31
logic [SAMPLE_WIDTH-1:0] product_d [PARALLEL_SAMPLES]; // 1Q15
logic signed [SAMPLE_WIDTH-1:0] data_in_reg [PARALLEL_SAMPLES]; // 1Q15
logic signed [17:0] scale_factor_reg; // 2Q16
logic signed [33:0] product [PARALLEL_SAMPLES]; // 3Q31
logic signed [SAMPLE_WIDTH-1:0] product_d [PARALLEL_SAMPLES]; // 1Q15
logic [3:0] valid_d;

always_ff @(posedge clk) begin
if (reset) begin
valid_d <= '0;
end
scale_factor_reg <= scale_factor; // always update scale factor
if (scale_factor.valid && scale_factor.ready) begin
scale_factor_reg <= scale_factor.data; // always update scale factor
end
if (data_in.valid && data_in.ready) begin
for (int i = 0; i < PARALLEL_SAMPLES; i++) begin
data_in_reg[i] <= data_in.data[i*SAMPLE_WIDTH+:SAMPLE_WIDTH]; // 1Q15*2Q16 = 3Q31
Expand All @@ -33,6 +35,7 @@ end

assign data_out.valid = valid_d[3];
assign data_in.ready = data_out.ready;
assign scale_factor.ready = 1'b1;

endmodule

Expand All @@ -47,11 +50,14 @@ module dac_prescaler_sv_wrapper #(
input [SAMPLE_WIDTH*PARALLEL_SAMPLES-1:0] data_in,
input data_in_valid,
output data_in_ready,
input [17:0] scale_factor // 2Q16 (2's complement)
input [17:0] scale_factor, // 2Q16 (2's complement)
input scale_factor_valid,
output scale_factor_ready
);

Axis_If #(.DWIDTH(SAMPLE_WIDTH*PARALLEL_SAMPLES)) data_out_if();
Axis_If #(.DWIDTH(SAMPLE_WIDTH*PARALLEL_SAMPLES)) data_in_if();
Axis_If #(.DWIDTH(18)) scale_factor_if();

dac_prescaler #(
.SAMPLE_WIDTH(SAMPLE_WIDTH),
Expand All @@ -61,7 +67,7 @@ dac_prescaler #(
.reset,
.data_out(data_out_if),
.data_in(data_in_if),
.scale_factor(scale_factor)
.scale_factor(scale_factor_if)
);

assign data_out = data_out_if.data;
Expand All @@ -72,5 +78,9 @@ assign data_in_if.data = data_in;
assign data_in_if.valid = data_in_valid;
assign data_in_ready = data_in_if.ready;

assign scale_factor_if.data = scale_factor;
assign scale_factor_if.valid = scale_factor_valid;
assign scale_factor_ready = scale_factor_if.ready;

endmodule

8 changes: 6 additions & 2 deletions dds_test.srcs/sources_1/new/dac_prescaler_wrapper.v
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ module dac_prescaler_wrapper (
input [255:0] s_axis_tdata,
input s_axis_tvalid,
output s_axis_tready,
input [17:0] scale_factor // 2Q16 (2's complement)
input [31:0] s_axis_scale_tdata, // 2Q16 (2's complement)
input s_axis_scale_tvalid,
output s_axis_scale_tready
);

dac_prescaler_sv_wrapper #(
Expand All @@ -21,7 +23,9 @@ dac_prescaler_sv_wrapper #(
.data_in(s_axis_tdata),
.data_in_valid(s_axis_tvalid),
.data_in_ready(s_axis_tready),
.scale_factor(scale_factor)
.scale_factor(s_axis_scale_tdata[17:0]),
.scale_factor_valid(s_axis_scale_tvalid),
.scale_factor_ready(s_axis_scale_tready)
);


Expand Down
10 changes: 5 additions & 5 deletions dds_test.srcs/sources_1/new/dds_wrapper.v
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ module dds_wrapper (
output [1023:0] cos_out_tdata,
output cos_out_tvalid,
input cos_out_tready,
input [23:0] phase_inc_in_tdata,
input [31:0] phase_inc_in_tdata,
input phase_inc_in_tvalid,
output phase_inc_in_tready,
input [3:0] cos_scale_in_tdata,
input [31:0] cos_scale_in_tdata,
input cos_scale_in_tvalid,
output cos_scale_in_tready
);

dds_sv_wrapper #(
.PHASE_BITS(24),
.PHASE_BITS(32),
.OUTPUT_WIDTH(16),
.QUANT_BITS(12),
.QUANT_BITS(20),
.PARALLEL_SAMPLES(64)
) dds_sv_wrapper_i (
.clk(clk),
Expand All @@ -27,7 +27,7 @@ dds_sv_wrapper #(
.phase_inc_in_data(phase_inc_in_tdata),
.phase_inc_in_valid(phase_inc_in_tvalid),
.phase_inc_in_ready(phase_inc_in_tready),
.cos_scale_in_data(cos_scale_in_tdata),
.cos_scale_in_data(cos_scale_in_tdata[3:0]),
.cos_scale_in_valid(cos_scale_in_tvalid),
.cos_scale_in_ready(cos_scale_in_tready)
);
Expand Down
4 changes: 2 additions & 2 deletions dds_test.srcs/sources_1/new/lmh6401_spi_wrapper.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module lmh6401_spi_wrapper (
input wire clk, reset_n,
input [16:0] data_in_tdata,
input [31:0] data_in_tdata,
input data_in_tvalid,
output data_in_tready,
output [1:0] cs_n,
Expand All @@ -15,7 +15,7 @@ lmh6401_spi #(
) lmh6401_spi_i (
.clk(clk),
.reset(~reset_n),
.addr_in(data_in_tdata[16:16]),
.addr_in(data_in_tdata[16]),
.data_in(data_in_tdata[15:0]),
.data_in_valid(data_in_tvalid),
.data_in_ready(data_in_tready),
Expand Down
2 changes: 1 addition & 1 deletion dds_test.srcs/sources_1/new/noise_event_tracker.sv
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ generate begin: fifo_gen

fifo #(
.DATA_WIDTH(SAMPLE_WIDTH+COUNT_BITS),
.ADDR_WIDTH(2) // does not need to be deep at all since samples are arriving at such a low rate
.ADDR_WIDTH(5) // does not need to be deep at all since samples are arriving at such a low rate
) fifo_i (
.clk,
.reset,
Expand Down
6 changes: 3 additions & 3 deletions dds_test.srcs/sources_1/new/noise_event_tracker_wrapper.v
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module noise_event_tracker_wrapper (
input s02_axis_tvalid,
output s02_axis_tready,

input [34:0] s_axis_config_tdata,
input [63:0] s_axis_config_tdata,
input s_axis_config_tvalid,
output s_axis_config_tready
);
Expand All @@ -25,7 +25,7 @@ noise_event_tracker_sv_wrapper #(
.BUFFER_DEPTH(32768),
.SAMPLE_WIDTH(16),
.AXI_MM_WIDTH(128),
.DECIMATION_BELOW_THRESH(10000),
.DECIMATION_BELOW_THRESH(16000),
.COUNT_BITS(40),
.TIMESTAMP_BUFFER_DEPTH(1024)
) noise_event_tracker_sv_wrapper_i (
Expand All @@ -41,7 +41,7 @@ noise_event_tracker_sv_wrapper #(
.data_in_02(s02_axis_tdata),
.data_in_02_valid(s02_axis_tvalid),
.data_in_02_ready(s02_axis_tready),
.config_in(s_axis_config_tdata),
.config_in(s_axis_config_tdata[34:0]),
.config_in_valid(s_axis_config_tvalid),
.config_in_ready(s_axis_config_tready)
);
Expand Down
Empty file added dds_test.tsm
Empty file.
101 changes: 101 additions & 0 deletions pynq/noise_buffer_overlay.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import os
from pynq import Overlay
from pynq import allocate
import xrfclk
import numpy as np
import matplotlib.pyplot as plt
from axitimer import AxiTimerDriver
from axitxfifo import AxiStreamFifoDriver
import scipy.signal
import scipy.io
import time
import serial

class NoiseOverlay(Overlay):
def __init__(self, bitfile_name=None, dbg=False, plot=False, **kwargs):
if bitfile_name is None:
this_dir = os.path.dirname(__file__)
bitfile_name = os.path.join(this_dir, 'hw', 'top.bit')
if dbg:
print(f'loading bitfile {bitfile_name}')
super().__init__(bitfile_name, **kwargs)
if dbg:
print('loaded bitstream')
time.sleep(0.5)
# get IPs
self.dma_recv = self.axi_dma_0.recvchannel
self.pinc = [self.dds_hier_0.axi_fifo_pinc_0, self.dds_hier_1.axi_fifo_pinc_1]
self.dac_coarse_scale = [self.dds_hier_0.axi_fifo_scale_0, self.dds_hier_1.axi_fifo_scale_1]
self.dac_fine_scale = [self.dds_hier_0.axi_fifo_dac_scale_0, self.dds_hier_1.axi_fifo_dac_scale_1]
self.timer = self.axi_timer_0
self.lmh6401 = self.lmh6401_hier.axi_fifo_lmh6401
self.noise_buffer = self.noise_tracker.axi_fifo_noise_buf_cfg

xrfclk.set_ref_clks(lmk_freq=122.88, lmx_freq=409.6)
if dbg:
print('set clocks')

self.f_samp = 4.096e9 # Hz
self.phase_bits = 32
self.timer.start_tmr()
self.axi_mm_width_words = 8 # 128-bit / 16 bit/word
self.noise_buffer_sample_depth = 2**15
self.noise_buffer_tstamp_depth = 2**10
self.dma_frame_size = (self.noise_buffer_sample_depth + self.noise_buffer_tstamp_depth) * self.axi_mm_width_words
self.dma_frame_shape = (self.dma_frame_size,)
# we can use unsigned types since the noise will always be a positive number
self.dma_buffer = allocate(shape=self.dma_frame_shape, dtype=np.uint16)
self.dbg = dbg
self.plot = plot
self.t_sleep = 0.008
# seems like there are sometimes AXI transaction reorderings, so add a delay as a
# sort of "manual fence"
# having a single AXI-slave device with multiple registers instead of
# separate AXI GPIOs should prevent issues arising from transaction reordering

def set_freq_hz(self, freq_hz, channel = 0):
pinc = int((freq_hz/self.f_samp)*(2**self.phase_bits))
if self.dbg:
print(f'setting pinc to {pinc} ({freq_hz:.3e}Hz)')
# send_tx_pkt accepts a list of 32-bit integers to send
self.pinc[channel].send_tx_pkt([pinc])
time.sleep(self.t_sleep)

def set_dac_atten_dB(self, atten_dB, channel = 0):
scale = round(atten_dB/6)
if scale < 0 or scale > 15:
raise ValueError("cannot set attenuation less than 0dB or more than 90dB")
if self.dbg:
print(f'setting cos_scale to {scale} ({6*scale}dB attenuation)')
self.dac_coarse_scale[channel].send_tx_pkt([scale])
time.sleep(self.t_sleep)

def set_dac_scale_factor(self, scale, channel = 0):
# scale is 2Q16, so quantize appropriately
quant = int(scale * 2**16)
if (quant >> 16) > 1 or (quant >> 16) < -2:
raise ValueError(f'cannot quantize {scale} to 2Q16')
if quant < 0:
quant += 2**18
# write to fifo
if self.dbg:
print(f'setting dac_prescale scale_factor to {quant / 2**16 - (0 if quant < 2**17 else 4)} ({quant:05x})')
self.dac_fine_scale[channel].send_tx_pkt([quant])
time.sleep(self.t_sleep)

def set_vga_atten_dB(self, atten_dB, channel = 0):
atten_dB = round(atten_dB)
if atten_dB < 0 or atten_dB > 32:
raise ValueError("atten_dB out of range, pick a number between 0 and 32dB")
packet = 0x0200 | (atten_dB & 0x3f) # address 0x02, 6-bit data atten_dB
packet |= channel << 16 # address/channel ID is above 16-bit address+data
if self.dbg:
print(f'setting vga attenuation to {atten_dB}dB')
print(f'packet = {hex(packet)}')
self.lmh6401.send_tx_pkt([packet])
time.sleep(self.t_sleep)

def dma(self):
time.sleep(self.t_sleep)
self.dma_recv.transfer(self.dma_buffer)
time.sleep(self.t_sleep)
Loading

0 comments on commit c725162

Please sign in to comment.