246 lines
8.1 KiB
Systemverilog
246 lines
8.1 KiB
Systemverilog
`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
|