fpga: x400: update signals to run on two domains

Original-commit: 982ea5b2d85c5a120569d80be3c53b54fdd670d3
This commit is contained in:
Javier Valenzuela
2023-10-25 14:14:48 -05:00
committed by Aki Tomita
parent e67c1f9ed4
commit ddbff804ed
5 changed files with 217 additions and 136 deletions
+52 -26
View File
@@ -22,8 +22,8 @@ module rfdc_timing_control #(
parameter NUM_DBOARDS = 2
) (
// Clocks and resets
input wire clk,
input wire rst,
input wire [ 1*NUM_DBOARDS-1:0] clk,
input wire [ 1*NUM_DBOARDS-1:0] rst,
// CtrlPort Slave (from RFNoC Radio Block)
input wire [ 1*NUM_DBOARDS-1:0] s_ctrlport_req_wr,
@@ -35,18 +35,16 @@ module rfdc_timing_control #(
output wire [ 32*NUM_DBOARDS-1:0] s_ctrlport_resp_data,
// RF Reset Control
output reg start_nco_reset,
input wire nco_reset_done,
output reg adc_reset_pulse,
output reg dac_reset_pulse
output reg start_nco_reset,
input wire nco_reset_done,
output reg [ 1*NUM_DBOARDS-1:0] adc_reset_pulse,
output reg [ 1*NUM_DBOARDS-1:0] dac_reset_pulse
);
`include "regmap/rfdc_timing_regmap_utils.vh"
// Reset registers
reg [NUM_DBOARDS-1:0] reg_nco_reset_start = 0;
reg [NUM_DBOARDS-1:0] reg_adc_reset_pulse = 0;
reg [NUM_DBOARDS-1:0] reg_dac_reset_pulse = 0;
genvar db;
generate
@@ -64,6 +62,22 @@ module rfdc_timing_control #(
reg [ 31:0] nco_ctrlport_resp_data;
wire [ 1:0] nco_ctrlport_resp_status = 2'b0;
wire nco_reset_done_clk;
// When asserted, nco_reset_done will stay high until the next start_nco_reset
// pulse, which by software design will not happen until this synchronizer
// propagates and the converted nco_reset_done_clk is read.
synchronizer #(
.STAGES (2),
.WIDTH (1),
.INITIAL_VAL (1'h0)
) synchronizer_nco_reset_done (
.clk (clk[db]),
.rst (rst[db]),
.in (nco_reset_done),
.out (nco_reset_done_clk)
);
assign nco_ctrlport_req_wr = s_ctrlport_req_wr [ 1*db+: 1];
assign nco_ctrlport_req_rd = s_ctrlport_req_rd [ 1*db+: 1];
assign nco_ctrlport_req_addr = s_ctrlport_req_addr [20*db+:20];
@@ -77,16 +91,16 @@ module rfdc_timing_control #(
// RF Reset Control
//-----------------------------------------------------------------------
always @(posedge clk) begin
if (rst) begin
always @(posedge clk[db]) begin
if (rst[db]) begin
nco_ctrlport_resp_ack <= 0;
reg_nco_reset_start[db] <= 0;
nco_ctrlport_resp_data <= 'bX;
end else begin
// Default assignments
reg_nco_reset_start[db] <= 0;
reg_adc_reset_pulse[db] <= 0;
reg_dac_reset_pulse[db] <= 0;
adc_reset_pulse[db] <= 0;
dac_reset_pulse[db] <= 0;
nco_ctrlport_resp_ack <= 0;
nco_ctrlport_resp_data <= 0;
@@ -95,7 +109,7 @@ module rfdc_timing_control #(
case (nco_ctrlport_req_addr)
NCO_RESET_REG: begin
nco_ctrlport_resp_ack <= 1;
nco_ctrlport_resp_data[NCO_RESET_DONE] <= nco_reset_done;
nco_ctrlport_resp_data[NCO_RESET_DONE] <= nco_reset_done_clk;
end
GEARBOX_RESET_REG: begin
nco_ctrlport_resp_ack <= 1;
@@ -112,8 +126,8 @@ module rfdc_timing_control #(
end
GEARBOX_RESET_REG: begin
nco_ctrlport_resp_ack <= 1;
reg_adc_reset_pulse[db] <= nco_ctrlport_req_data[ADC_RESET];
reg_dac_reset_pulse[db] <= nco_ctrlport_req_data[DAC_RESET];
adc_reset_pulse[db] <= nco_ctrlport_req_data[ADC_RESET];
dac_reset_pulse[db] <= nco_ctrlport_req_data[DAC_RESET];
end
endcase
end
@@ -125,24 +139,36 @@ module rfdc_timing_control #(
//---------------------------------------------------------------------------
// Merge Resets
// Merge NCO Start
//---------------------------------------------------------------------------
//
// There are multiple DBs but only one reset signal for each RF component.
// Since the reset is simply a single cycle pulse, we OR the reset registers
// for each daughter board together.
// There are multiple DBs but only one NCO start pulse, which is expected to
// happen on the clk[0] domain. This pulse will be used to align NCO updates
// to the next SYSREF pulse, which is related to all clk[db] domains.
//
//---------------------------------------------------------------------------
always @(posedge clk) begin
if (rst) begin
wire [NUM_DBOARDS-1:0] reg_nco_reset_start_clk0 = 0;
genvar db_i;
generate
for (db_i = 0; db_i < NUM_DBOARDS; db_i = db_i+1) begin : gen_nco_start_sync
pulse_synchronizer #(
.MODE("PULSE"), .STAGES(2)
) pulse_sync_nco_start (
.clk_a(clk[db_i]), .rst_a(rst[db_i]), .pulse_a(reg_nco_reset_start[db_i]), .busy_a(),
.clk_b(clk[0]), .pulse_b(reg_nco_reset_start_clk0[db_i])
);
end
endgenerate
always @(posedge clk[0]) begin
if (rst[0]) begin
start_nco_reset <= 0;
adc_reset_pulse <= 0;
dac_reset_pulse <= 0;
end else begin
start_nco_reset <= |reg_nco_reset_start;
adc_reset_pulse <= |reg_adc_reset_pulse;
dac_reset_pulse <= |reg_dac_reset_pulse;
start_nco_reset <= |reg_nco_reset_start_clk0;
end
end