Files
reflectometer_fpga_project/designs/reflectometer_base/reflectometer.sv

246 lines
8.1 KiB
Systemverilog
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

`timescale 1 ns / 1 ns
`include "interfaces.svh"
module reflectometer_top #(
parameter int unsigned DAC_DATA_WIDTH = 14,
parameter int unsigned ADC_DATA_WIDTH = 12,
parameter int unsigned PACK_FACTOR = 1,
parameter int unsigned PROCESS_MODE = 0,
parameter int unsigned ZERO_LEVEL = 8192,
parameter int unsigned ACCUM_WIDTH = 32,
parameter int unsigned N_MAX = 4096,
parameter int unsigned WINDOW_SIZE = 65,
parameter int unsigned PACKET_SIZE = 1024
)(
input wire clk_in,
input wire rst_n,
output wire locked,
// Accumulator AXI-S bus
input wire clk_axis_accumulator, // GMII PHY RX clock
axis_if.master axis_accumulator,
// Control AXI-S bus
input wire clk_axis_control, // GMII PHY TX clock
axis_if.slave axis_control,
// RTL-MAC handshake
input wire request_ready,
output wire send_request,
// DAC
output wire dac_clk_o,
output wire [DAC_DATA_WIDTH-1:0] dac_data,
output wire dac_wrt,
// ADC
output wire adc_clk_o,
input wire [ADC_DATA_WIDTH-1:0] adc_data,
input wire adc_otr
);
// -------------------------------------------------------------------------
// Generated clocks for controller
// Need to create this IP in Vivado:
// input resetn
// input clk_200 : 200 MHz : Reference clock
// output clk_adc_65 : 65 MHz : ADC RTL clock
// output clk_adc_65_180 : 65 MHz, phase 180 deg. : ADC PHY clock
// output clk_adc_125 : 125 MHz : DAC RTL clock
// output clk_adc_125_180 : 125 MHz, phase 180 deg. : DAC PHY clock
// output locked
// -------------------------------------------------------------------------
wire clk_sampler, clk_generator, clk_locked;
clk_wiz_ctrl_inst clk_wiz_inst
(
// Clock in ports
.clk_200(clk_in),
// Clock out ports
.clk_adc_65(clk_sampler),
.clk_adc_65_180(adc_clk_o),
.clk_dac_125(clk_generator),
.clk_dac_125_180(dac_clk_o),
// Status and control signals
.resetn(rst_n),
.locked(clk_locked)
);
assign locked = clk_locked;
// -------------------------------------------------------------------------
// Controller reset
// Use both external reset and clk_wiz lock
// -------------------------------------------------------------------------
wire ctrl_rst_n = rst_n & clk_locked;
// -------------------------------------------------------------------------
// Controller
// -------------------------------------------------------------------------
wire [31:0] dac_pulse_width;
wire [31:0] dac_pulse_period;
wire [DAC_DATA_WIDTH-1:0] dac_pulse_height;
wire [15:0] dac_pulse_num;
wire [31:0] adc_pulse_period;
wire [15:0] adc_pulse_num;
wire dac_start;
wire adc_start;
wire dac_rst;
wire adc_rst;
wire finish;
control #(
.DAC_DATA_WIDTH(DAC_DATA_WIDTH)
) udp_ctrl_inst (
.eth_clk_in (clk_axis_control),
.dac_clk_in (clk_generator),
.adc_clk_in (clk_sampler),
.rst_n (ctrl_rst_n),
.s_axis_tdata (axis_control.tdata),
.s_axis_tvalid (axis_control.tvalid),
.s_axis_tready (axis_control.tready),
.s_axis_tlast (axis_control.tlast),
.finish (finish),
.dac_pulse_width (dac_pulse_width),
.dac_pulse_period (dac_pulse_period),
.dac_pulse_height (dac_pulse_height),
.dac_pulse_num (dac_pulse_num),
.adc_pulse_period (adc_pulse_period),
.adc_pulse_num (adc_pulse_num),
.dac_start (dac_start),
.adc_start (adc_start),
.dac_rst (dac_rst),
.adc_rst (adc_rst)
);
//------------------------------------------------------------
// DAC -> ADC CDC
//------------------------------------------------------------
(* ASYNC_REG = "TRUE" *) logic [2:0] stretch; // 125/65~=2. Чтобы поймать единичный импульс, растянем его во времени
(* ASYNC_REG = "TRUE" *) logic [1:0] sync_DA;
wire dac_done_stretched;
wire generator_done, generator_request;
wire sampler_done, sampler_request;
always_ff @(posedge clk_generator or posedge dac_rst)
begin
if (dac_rst)
stretch <= 0;
else begin
stretch[0] <= generator_done;
stretch[1] <= stretch[0];
stretch[2] <= stretch[1];
end
end
assign dac_done_stretched = |stretch;
always_ff @(posedge clk_sampler or posedge adc_rst) begin
if (adc_rst)
sync_DA <= 0;
else begin
sync_DA[0] <= dac_done_stretched;
sync_DA[1] <= sync_DA[0];
end
end
assign sampler_request = sync_DA[1];
//------------------------------------------------------------
// ADC -> DAC CDC
//------------------------------------------------------------
(* ASYNC_REG = "TRUE" *) logic [1:0] sync_AD;
always_ff @(posedge clk_generator or posedge dac_rst) begin
if (dac_rst)
sync_AD <= 0;
else begin
sync_AD[0] <= sampler_done;
sync_AD[1] <= sync_AD[0];
end
end
assign generator_request = sync_AD[1];
//------------------------------------------------------------
// Generator (DAC)
//------------------------------------------------------------
generator #(
.DATA_WIDTH(DAC_DATA_WIDTH),
.ZERO_LEVEL(ZERO_LEVEL)
) generator_inst (
.clk_dac(clk_generator),
.rst(dac_rst),
.start(dac_start),
.pulse_width(dac_pulse_width),
.pulse_period(dac_pulse_period),
.pulse_height(dac_pulse_height),
.pulse_num(dac_pulse_num),
.dac_out(dac_data),
.done(generator_done),
.request(generator_request)
);
assign dac_wrt = dac_clk_o;
// -------------------------------------------------------------------------
// Sampler (ADC)
// -------------------------------------------------------------------------
wire [ADC_DATA_WIDTH*PACK_FACTOR-1:0] sampler_m_axis_tdata;
wire sampler_m_axis_tvalid;
sampler #(
.DATA_WIDTH(ADC_DATA_WIDTH),
.PACK_FACTOR(PACK_FACTOR),
.PROCESS_MODE(PROCESS_MODE)
) sampler_dut (
.clk_in(clk_sampler),
.rst(adc_rst),
.data_in(adc_data),
.out_of_range(adc_otr),
.m_axis_tdata(sampler_m_axis_tdata),
.m_axis_tvalid(sampler_m_axis_tvalid),
.smp_num(adc_pulse_period),
.done(sampler_done),
.request(sampler_request)
);
// -------------------------------------------------------------------------
// Accumulator
// -------------------------------------------------------------------------
accumulator_top #(
.DATA_WIDTH(ADC_DATA_WIDTH),
.ACCUM_WIDTH(ACCUM_WIDTH),
.N_MAX(N_MAX),
.WINDOW_SIZE(WINDOW_SIZE),
.PACKET_SIZE(PACKET_SIZE)
) accumulator_top_dut (
.clk_in(clk_sampler),
.rst(adc_rst),
.s_axis_tdata(sampler_m_axis_tdata),
.s_axis_tvalid(sampler_m_axis_tvalid),
.start(adc_start),
.smp_num(adc_pulse_period),
.seq_num(adc_pulse_num),
.req_ready(request_ready),
.send_req(send_request),
.eth_clk_in(clk_axis_accumulator),
.m_axis_tdata(axis_accumulator.tdata),
.m_axis_tvalid(axis_accumulator.tvalid),
.m_axis_tready(axis_accumulator.tready),
.m_axis_tlast(axis_accumulator.tlast),
.finish(finish)
);
endmodule