fpga: x400: Add GPIO control via ATR and DB state
Original-commit: 9335939b9b3ab85cee5908ff3357f9e7819e3366
This commit is contained in:
committed by
Wade Fife
parent
4edae39d9e
commit
962d01e583
+379
-54
@@ -9,10 +9,23 @@
|
||||
//
|
||||
// This module contains the motherboard registers for the DIO
|
||||
// auxiliary board and the logic to drive these GPIO signals.
|
||||
// Arbitration between different sources to control the state
|
||||
// of the GPIO lines includes support for the following sources:
|
||||
// - s_ctrlport_* (combination of CtrlPort from PS AXI and radio blocks)
|
||||
// - PS dio control from Processing System's GPIOs
|
||||
// - ATR state (up to two DBs)
|
||||
// - User Application
|
||||
// - radio-controlled digital bus interface
|
||||
// For a visual representation of how the different sources are
|
||||
// arbitrated, as well as representation on what each source control
|
||||
// register refers to, please refer to the "Front-Panel Programmable
|
||||
// GPIOs" section of the USRP Manual.
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// REG_BASE : Base address to use for registers.
|
||||
// REG_BASE : Base address to use for registers.
|
||||
// REG_SIZE : Register space size.
|
||||
// NUM_DBOARDS : Number of daughterboards to support.
|
||||
//
|
||||
|
||||
`default_nettype none
|
||||
@@ -20,7 +33,8 @@
|
||||
|
||||
module x4xx_dio #(
|
||||
parameter REG_BASE = 0,
|
||||
parameter REG_SIZE = 'h20
|
||||
parameter REG_SIZE = 'h30,
|
||||
parameter NUM_DBOARDS = 2
|
||||
) (
|
||||
// Slave ctrlport interface
|
||||
input wire ctrlport_clk,
|
||||
@@ -43,11 +57,31 @@ module x4xx_dio #(
|
||||
output wire [11:0] gpio_out_a,
|
||||
output wire [11:0] gpio_out_b,
|
||||
|
||||
// GPIO to application (async)
|
||||
output wire [11:0] gpio_in_fabric_a,
|
||||
output wire [11:0] gpio_in_fabric_b,
|
||||
input wire [11:0] gpio_out_fabric_a,
|
||||
input wire [11:0] gpio_out_fabric_b
|
||||
// ATR GPIO Control (ctrlport_clk)
|
||||
input wire [NUM_DBOARDS*32-1:0] atr_gpio_out,
|
||||
input wire [NUM_DBOARDS*32-1:0] atr_gpio_ddr,
|
||||
|
||||
// PS GPIO Control from Block Design (async)
|
||||
input wire [31:0] ps_gpio_out,
|
||||
input wire [31:0] ps_gpio_ddr,
|
||||
|
||||
// Digital Interface Control (ctrlport_clk)
|
||||
input wire [31:0] digital_ifc_gpio_out_radio0,
|
||||
input wire [31:0] digital_ifc_gpio_ddr_radio0,
|
||||
input wire [31:0] digital_ifc_gpio_out_radio1,
|
||||
input wire [31:0] digital_ifc_gpio_ddr_radio1,
|
||||
|
||||
// GPIO to user application (async)
|
||||
// User application relies on the local direction register
|
||||
// for GPIO direction control. For this reason, we skip
|
||||
// a mux to select between the user application and the
|
||||
// local register direction control in the mux chain, and
|
||||
// propagate their shared direction(from the local register)
|
||||
// to the remainder of the mux chain.
|
||||
output wire [11:0] user_app_in_a,
|
||||
output wire [11:0] user_app_in_b,
|
||||
input wire [11:0] user_app_out_a,
|
||||
input wire [11:0] user_app_out_b
|
||||
);
|
||||
|
||||
`include "../../lib/rfnoc/core/ctrlport.vh"
|
||||
@@ -70,6 +104,16 @@ module x4xx_dio #(
|
||||
reg [DIO_WIDTH-1:0] dio_master_b = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_output_a = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_output_b = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_source_a = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_source_b = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_radio_a = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_radio_b = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_interface_a = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_interface_b = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_override_a = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_override_b = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_sw_ctrl_a = {DIO_WIDTH {1'b0}};
|
||||
reg [DIO_WIDTH-1:0] dio_sw_ctrl_b = {DIO_WIDTH {1'b0}};
|
||||
wire [DIO_WIDTH-1:0] dio_input_a;
|
||||
wire [DIO_WIDTH-1:0] dio_input_b;
|
||||
|
||||
@@ -93,6 +137,16 @@ module x4xx_dio #(
|
||||
dio_master_b <= {DIO_WIDTH {1'b0}};
|
||||
dio_output_a <= {DIO_WIDTH {1'b0}};
|
||||
dio_output_b <= {DIO_WIDTH {1'b0}};
|
||||
dio_source_a <= {DIO_WIDTH {1'b0}};
|
||||
dio_source_b <= {DIO_WIDTH {1'b0}};
|
||||
dio_radio_a <= {DIO_WIDTH {1'b0}};
|
||||
dio_radio_b <= {DIO_WIDTH {1'b0}};
|
||||
dio_interface_a <= {DIO_WIDTH {1'b0}};
|
||||
dio_interface_b <= {DIO_WIDTH {1'b0}};
|
||||
dio_override_a <= {DIO_WIDTH {1'b0}};
|
||||
dio_override_b <= {DIO_WIDTH {1'b0}};
|
||||
dio_sw_ctrl_a <= {DIO_WIDTH {1'b0}};
|
||||
dio_sw_ctrl_b <= {DIO_WIDTH {1'b0}};
|
||||
|
||||
end else begin
|
||||
// Write registers
|
||||
@@ -104,18 +158,43 @@ module x4xx_dio #(
|
||||
|
||||
case (s_ctrlport_req_addr)
|
||||
REG_BASE + DIO_MASTER_REGISTER: begin
|
||||
dio_master_a <= s_ctrlport_req_data[DIO_MASTER_A_MSB:DIO_MASTER_A];
|
||||
dio_master_b <= s_ctrlport_req_data[DIO_MASTER_B_MSB:DIO_MASTER_B];
|
||||
dio_master_a <= s_ctrlport_req_data[DIO_PORT_A_MSB:DIO_PORT_A];
|
||||
dio_master_b <= s_ctrlport_req_data[DIO_PORT_B_MSB:DIO_PORT_B];
|
||||
end
|
||||
|
||||
REG_BASE + DIO_DIRECTION_REGISTER: begin
|
||||
dio_direction_a <= s_ctrlport_req_data[DIO_DIRECTION_A_MSB:DIO_DIRECTION_A];
|
||||
dio_direction_b <= s_ctrlport_req_data[DIO_DIRECTION_B_MSB:DIO_DIRECTION_B];
|
||||
dio_direction_a <= s_ctrlport_req_data[DIO_PORT_A_MSB:DIO_PORT_A];
|
||||
dio_direction_b <= s_ctrlport_req_data[DIO_PORT_B_MSB:DIO_PORT_B];
|
||||
end
|
||||
|
||||
REG_BASE + DIO_OUTPUT_REGISTER: begin
|
||||
dio_output_a <= s_ctrlport_req_data[DIO_OUTPUT_A_MSB:DIO_OUTPUT_A];
|
||||
dio_output_b <= s_ctrlport_req_data[DIO_OUTPUT_B_MSB:DIO_OUTPUT_B];
|
||||
dio_output_a <= s_ctrlport_req_data[DIO_PORT_A_MSB:DIO_PORT_A];
|
||||
dio_output_b <= s_ctrlport_req_data[DIO_PORT_B_MSB:DIO_PORT_B];
|
||||
end
|
||||
|
||||
REG_BASE + DIO_SOURCE_REGISTER: begin
|
||||
dio_source_a <= s_ctrlport_req_data[DIO_PORT_A_MSB:DIO_PORT_A];
|
||||
dio_source_b <= s_ctrlport_req_data[DIO_PORT_B_MSB:DIO_PORT_B];
|
||||
end
|
||||
|
||||
REG_BASE + RADIO_SOURCE_REGISTER: begin
|
||||
dio_radio_a <= s_ctrlport_req_data[DIO_PORT_A_MSB:DIO_PORT_A];
|
||||
dio_radio_b <= s_ctrlport_req_data[DIO_PORT_B_MSB:DIO_PORT_B];
|
||||
end
|
||||
|
||||
REG_BASE + INTERFACE_DIO_SELECT: begin
|
||||
dio_interface_a <= s_ctrlport_req_data[DIO_PORT_A_MSB:DIO_PORT_A];
|
||||
dio_interface_b <= s_ctrlport_req_data[DIO_PORT_B_MSB:DIO_PORT_B];
|
||||
end
|
||||
|
||||
REG_BASE + DIO_OVERRIDE: begin
|
||||
dio_override_a <= s_ctrlport_req_data[DIO_PORT_A_MSB:DIO_PORT_A];
|
||||
dio_override_b <= s_ctrlport_req_data[DIO_PORT_B_MSB:DIO_PORT_B];
|
||||
end
|
||||
|
||||
REG_BASE + SW_DIO_CONTROL: begin
|
||||
dio_sw_ctrl_a <= s_ctrlport_req_data[DIO_PORT_A_MSB:DIO_PORT_A];
|
||||
dio_sw_ctrl_b <= s_ctrlport_req_data[DIO_PORT_B_MSB:DIO_PORT_B];
|
||||
end
|
||||
|
||||
// No register implementation for provided address
|
||||
@@ -131,6 +210,7 @@ module x4xx_dio #(
|
||||
end
|
||||
endcase
|
||||
|
||||
|
||||
// Read registers
|
||||
end else if (s_ctrlport_req_rd) begin
|
||||
// Acknowledge by default
|
||||
@@ -140,23 +220,48 @@ module x4xx_dio #(
|
||||
|
||||
case (s_ctrlport_req_addr)
|
||||
REG_BASE + DIO_MASTER_REGISTER: begin
|
||||
s_ctrlport_resp_data[DIO_MASTER_A_MSB:DIO_MASTER_A] <= dio_master_a;
|
||||
s_ctrlport_resp_data[DIO_MASTER_B_MSB:DIO_MASTER_B] <= dio_master_b;
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_master_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_master_b;
|
||||
end
|
||||
|
||||
REG_BASE + DIO_DIRECTION_REGISTER: begin
|
||||
s_ctrlport_resp_data[DIO_DIRECTION_A_MSB:DIO_DIRECTION_A] <= dio_direction_a;
|
||||
s_ctrlport_resp_data[DIO_DIRECTION_B_MSB:DIO_DIRECTION_B] <= dio_direction_b;
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_direction_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_direction_b;
|
||||
end
|
||||
|
||||
REG_BASE + DIO_OUTPUT_REGISTER: begin
|
||||
s_ctrlport_resp_data[DIO_OUTPUT_A_MSB:DIO_OUTPUT_A] <= dio_output_a;
|
||||
s_ctrlport_resp_data[DIO_OUTPUT_B_MSB:DIO_OUTPUT_B] <= dio_output_b;
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_output_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_output_b;
|
||||
end
|
||||
|
||||
REG_BASE + DIO_INPUT_REGISTER: begin
|
||||
s_ctrlport_resp_data[DIO_INPUT_A_MSB:DIO_INPUT_A] <= dio_input_a;
|
||||
s_ctrlport_resp_data[DIO_INPUT_B_MSB:DIO_INPUT_B] <= dio_input_b;
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_input_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_input_b;
|
||||
end
|
||||
|
||||
REG_BASE + DIO_SOURCE_REGISTER: begin
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_source_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_source_b;
|
||||
end
|
||||
|
||||
REG_BASE + RADIO_SOURCE_REGISTER: begin
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_radio_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_radio_b;
|
||||
end
|
||||
|
||||
REG_BASE + INTERFACE_DIO_SELECT: begin
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_interface_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_interface_b;
|
||||
end
|
||||
|
||||
REG_BASE + DIO_OVERRIDE: begin
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_override_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_override_b;
|
||||
end
|
||||
|
||||
REG_BASE + SW_DIO_CONTROL: begin
|
||||
s_ctrlport_resp_data[DIO_PORT_A_MSB:DIO_PORT_A] <= dio_sw_ctrl_a;
|
||||
s_ctrlport_resp_data[DIO_PORT_B_MSB:DIO_PORT_B] <= dio_sw_ctrl_b;
|
||||
end
|
||||
|
||||
// No register implementation for provided address
|
||||
@@ -198,31 +303,205 @@ module x4xx_dio #(
|
||||
);
|
||||
|
||||
// Forward raw input to user application
|
||||
assign gpio_in_fabric_a = gpio_in_a;
|
||||
assign gpio_in_fabric_b = gpio_in_b;
|
||||
assign user_app_in_a = gpio_in_a;
|
||||
assign user_app_in_b = gpio_in_b;
|
||||
|
||||
// Direction control
|
||||
assign gpio_en_a = dio_direction_a;
|
||||
assign gpio_en_b = dio_direction_b;
|
||||
wire [DIO_WIDTH-1:0] gpio_out_sw_a;
|
||||
wire [DIO_WIDTH-1:0] gpio_out_sw_b;
|
||||
|
||||
// Output assignment depending on master
|
||||
generate
|
||||
genvar i;
|
||||
for (i = 0; i < DIO_WIDTH; i = i + 1) begin: dio_output_gen
|
||||
glitch_free_mux glitch_free_mux_dio_a (
|
||||
|
||||
reg atr_gpio_src_out_a_reg = 1'b0;
|
||||
reg atr_gpio_src_out_b_reg = 1'b0;
|
||||
reg atr_gpio_src_ddr_a_reg = 1'b0;
|
||||
reg atr_gpio_src_ddr_b_reg = 1'b0;
|
||||
|
||||
// 1) Select which radio drives the output
|
||||
always @ (posedge ctrlport_clk) begin
|
||||
if (ctrlport_rst) begin
|
||||
atr_gpio_src_out_a_reg <= 1'b0;
|
||||
atr_gpio_src_out_b_reg <= 1'b0;
|
||||
end else begin
|
||||
atr_gpio_src_out_a_reg <= atr_gpio_out[dio_radio_a[i]*32 + DIO_PORT_A + i];
|
||||
atr_gpio_src_out_b_reg <= atr_gpio_out[dio_radio_b[i]*32 + DIO_PORT_B + i];
|
||||
end
|
||||
end
|
||||
|
||||
// 2) Select which radio drives the direction
|
||||
always @ (posedge ctrlport_clk) begin
|
||||
if (ctrlport_rst) begin
|
||||
atr_gpio_src_ddr_a_reg <= 1'b0;
|
||||
atr_gpio_src_ddr_b_reg <= 1'b0;
|
||||
end else begin
|
||||
atr_gpio_src_ddr_a_reg <= atr_gpio_ddr[dio_radio_a[i]*32 + DIO_PORT_A + i];
|
||||
atr_gpio_src_ddr_b_reg <= atr_gpio_ddr[dio_radio_b[i]*32 + DIO_PORT_B + i];
|
||||
end
|
||||
end
|
||||
|
||||
// Select between the Digital Interface in each radio(INTERFACE_DIO_SELECT)
|
||||
wire dio_interface_mux_out_a;
|
||||
wire dio_interface_mux_out_b;
|
||||
wire dio_interface_mux_ddr_a;
|
||||
wire dio_interface_mux_ddr_b;
|
||||
|
||||
glitch_free_mux glitch_free_interface_out_mux_dio_a (
|
||||
.select (dio_interface_a[i]),
|
||||
.signal0 (digital_ifc_gpio_out_radio0[DIO_PORT_A + i]),
|
||||
.signal1 (digital_ifc_gpio_out_radio1[DIO_PORT_A + i]),
|
||||
.muxed_signal (dio_interface_mux_out_a)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_interface_out_mux_dio_b (
|
||||
.select (dio_interface_b[i]),
|
||||
.signal0 (digital_ifc_gpio_out_radio0[DIO_PORT_B + i]),
|
||||
.signal1 (digital_ifc_gpio_out_radio1[DIO_PORT_B + i]),
|
||||
.muxed_signal (dio_interface_mux_out_b)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_interface_ddr_mux_dio_a (
|
||||
.select (dio_interface_a[i]),
|
||||
.signal0 (digital_ifc_gpio_ddr_radio0[DIO_PORT_A + i]),
|
||||
.signal1 (digital_ifc_gpio_ddr_radio1[DIO_PORT_A + i]),
|
||||
.muxed_signal (dio_interface_mux_ddr_a)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_interface_ddr_mux_dio_b (
|
||||
.select (dio_interface_b[i]),
|
||||
.signal0 (digital_ifc_gpio_ddr_radio0[DIO_PORT_B + i]),
|
||||
.signal1 (digital_ifc_gpio_ddr_radio1[DIO_PORT_B + i]),
|
||||
.muxed_signal (dio_interface_mux_ddr_b)
|
||||
);
|
||||
|
||||
|
||||
// Select between ATR or Digital control(DIO_OVERRIDE)
|
||||
wire dio_override_mux_out_a;
|
||||
wire dio_override_mux_out_b;
|
||||
wire dio_override_mux_ddr_a;
|
||||
wire dio_override_mux_ddr_b;
|
||||
|
||||
glitch_free_mux glitch_free_override_out_mux_dio_a (
|
||||
.select (dio_override_a[i]),
|
||||
.signal0 (atr_gpio_src_out_a_reg),
|
||||
.signal1 (dio_interface_mux_out_a),
|
||||
.muxed_signal (dio_override_mux_out_a)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_override_out_mux_dio_b (
|
||||
.select (dio_override_b[i]),
|
||||
.signal0 (atr_gpio_src_out_b_reg),
|
||||
.signal1 (dio_interface_mux_out_b),
|
||||
.muxed_signal (dio_override_mux_out_b)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_override_ddr_mux_dio_a (
|
||||
.select (dio_override_a[i]),
|
||||
.signal0 (atr_gpio_src_ddr_a_reg),
|
||||
.signal1 (dio_interface_mux_ddr_a),
|
||||
.muxed_signal (dio_override_mux_ddr_a)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_override_ddr_mux_dio_b (
|
||||
.select (dio_override_b[i]),
|
||||
.signal0 (atr_gpio_src_ddr_b_reg),
|
||||
.signal1 (dio_interface_mux_ddr_b),
|
||||
.muxed_signal (dio_override_mux_ddr_b)
|
||||
);
|
||||
|
||||
|
||||
// SW source select
|
||||
// SW_DIO_CONTROL, select between PS and local register
|
||||
|
||||
wire dio_sw_control_mux_out_a;
|
||||
wire dio_sw_control_mux_out_b;
|
||||
wire dio_sw_control_mux_ddr_a;
|
||||
wire dio_sw_control_mux_ddr_b;
|
||||
|
||||
glitch_free_mux glitch_free_sw_control_out_mux_dio_a (
|
||||
.select (dio_sw_ctrl_a[i]),
|
||||
.signal0 (dio_output_a[i]),
|
||||
.signal1 (ps_gpio_out[DIO_PORT_A + i]),
|
||||
.muxed_signal (dio_sw_control_mux_out_a)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_sw_control_out_mux_dio_b (
|
||||
.select (dio_sw_ctrl_b[i]),
|
||||
.signal0 (dio_output_b[i]),
|
||||
.signal1 (ps_gpio_out[DIO_PORT_B + i]),
|
||||
.muxed_signal (dio_sw_control_mux_out_b)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_sw_control_ddr_mux_dio_a (
|
||||
.select (dio_sw_ctrl_a[i]),
|
||||
.signal0 (dio_direction_a[i]),
|
||||
.signal1 (ps_gpio_ddr[DIO_PORT_A + i]),
|
||||
.muxed_signal (dio_sw_control_mux_ddr_a)
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_sw_control_ddr_mux_dio_b (
|
||||
.select (dio_sw_ctrl_b[i]),
|
||||
.signal0 (dio_direction_b[i]),
|
||||
.signal1 (ps_gpio_ddr[DIO_PORT_B + i]),
|
||||
.muxed_signal (dio_sw_control_mux_ddr_b)
|
||||
);
|
||||
|
||||
|
||||
// DIO_MASTER_REGISTER Mux, select between SW_DIO_CONTROL
|
||||
// and user application
|
||||
// User application relies on the local direction register
|
||||
// for GPIO direction control. For this reason, we skip
|
||||
// a mux to select between the user application and the
|
||||
// local register direction control in the mux chain, and
|
||||
// propagate their shared direction(from the local register)
|
||||
// to the remainder of the mux chain.
|
||||
glitch_free_mux glitch_free_master_mux_dio_a (
|
||||
.select (dio_master_a[i]),
|
||||
.signal0 (gpio_out_fabric_a[i]),
|
||||
.signal1 (dio_output_a[i]),
|
||||
.signal0 (user_app_out_a[i]),
|
||||
.signal1 (dio_sw_control_mux_out_a),
|
||||
.muxed_signal (gpio_out_sw_a[i])
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_master_mux_dio_b (
|
||||
.select (dio_master_b[i]),
|
||||
.signal0 (user_app_out_b[i]),
|
||||
.signal1 (dio_sw_control_mux_out_b),
|
||||
.muxed_signal (gpio_out_sw_b[i])
|
||||
);
|
||||
|
||||
// DIO_SOURCE_REGISTER mux, select between (DIO_MASTER_REGISTER output) and
|
||||
// radio controlled source (DIO_OVERRIDE output).
|
||||
glitch_free_mux glitch_free_source_out_mux_dio_a (
|
||||
.select (dio_source_a[i]),
|
||||
.signal0 (gpio_out_sw_a[i]),
|
||||
.signal1 (dio_override_mux_out_a),
|
||||
.muxed_signal (gpio_out_a[i])
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_mux_dio_b (
|
||||
.select (dio_master_b[i]),
|
||||
.signal0 (gpio_out_fabric_b[i]),
|
||||
.signal1 (dio_output_b[i]),
|
||||
glitch_free_mux glitch_free_source_out_mux_dio_b (
|
||||
.select (dio_source_b[i]),
|
||||
.signal0 (gpio_out_sw_b[i]),
|
||||
.signal1 (dio_override_mux_out_b),
|
||||
.muxed_signal (gpio_out_b[i])
|
||||
);
|
||||
|
||||
// Direction control
|
||||
glitch_free_mux glitch_free_dir_mux_dio_a (
|
||||
.select (dio_source_a[i]),
|
||||
.signal0 (dio_sw_control_mux_ddr_a),
|
||||
.signal1 (dio_override_mux_ddr_a),
|
||||
.muxed_signal (gpio_en_a[i])
|
||||
);
|
||||
|
||||
glitch_free_mux glitch_free_dir_mux_dio_b (
|
||||
.select (dio_source_b[i]),
|
||||
.signal0 (dio_sw_control_mux_ddr_b),
|
||||
.signal1 (dio_override_mux_ddr_b),
|
||||
.muxed_signal (gpio_en_b[i])
|
||||
);
|
||||
end
|
||||
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
@@ -232,44 +511,90 @@ endmodule
|
||||
|
||||
|
||||
//XmlParse xml_on
|
||||
//<regmap name="DIO_REGMAP" readablestrobes="false" ettusguidelines="true">
|
||||
//<regmap name="DIO_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
|
||||
// <group name="DIO_REGS">
|
||||
// <info>
|
||||
// Registers to control the GPIO buffer direction on the FPGA connected to the DIO board.
|
||||
// Further registers enable the PS to control and read the GPIO lines as master.
|
||||
// Make sure the GPIO lines between FPGA and GPIO board are not driven by two drivers.
|
||||
// Set the DIO registers in @.PS_CPLD_BASE_REGMAP appropriately.
|
||||
// Registers to control the GPIO buffer direction on the FPGA connected to
|
||||
// the DIO board. Further registers enable different sources to control and
|
||||
// read the GPIO lines as master. The following diagram shows how source
|
||||
// selection multiplexers are arranged, as well as an indicator for the
|
||||
// register that control them. </br>
|
||||
// <img src = "..\..\..\..\..\host\docs\res\x4xx_dio_source_muxes.svg"
|
||||
// alt="Front-Panel Programmable GPIOs"/></br>
|
||||
// Make sure the GPIO lines between FPGA and GPIO board are not driven by
|
||||
// two drivers. Set the DIO registers in @.PS_CPLD_BASE_REGMAP appropriately.
|
||||
// </info>
|
||||
//
|
||||
// <register name="DIO_MASTER_REGISTER" offset="0x00" size="32">
|
||||
// <regtype name="DIO_CONTROL_REG" size="32">
|
||||
// <info>
|
||||
// Sets whether the DIO signal line is driven by this register interface or the user application.{br/}
|
||||
// 0 = user application is master, 1 = PS is master
|
||||
// Holds a single bit setting for DIO lines in both ports. One bit per pin.
|
||||
// </info>
|
||||
// <bitfield name="DIO_PORT_A" range="0..11" initialvalue="0"/>
|
||||
// <bitfield name="DIO_PORT_B" range="16..27" initialvalue="0"/>
|
||||
// </regtype>
|
||||
//
|
||||
// <register name="DIO_MASTER_REGISTER" offset="0x00" typename="DIO_CONTROL_REG">
|
||||
// <info>
|
||||
// Sets whether the DIO signal line is driven by this register interface
|
||||
// or the user application.{br/}
|
||||
// 0 = user application is master, 1 = output of @.SW_DIO_CONTROL is master
|
||||
// </info>
|
||||
// <bitfield name="DIO_MASTER_A" range="0..11" initialvalue="0"/>
|
||||
// <bitfield name="DIO_MASTER_B" range="16..27" initialvalue="0"/>
|
||||
// </register>
|
||||
// <register name="DIO_DIRECTION_REGISTER" offset="0x04" size="32">
|
||||
// <register name="DIO_DIRECTION_REGISTER" offset="0x04" typename="DIO_CONTROL_REG">
|
||||
// <info>
|
||||
// Set the direction of FPGA buffer connected to DIO ports on the DIO board.{br/}
|
||||
// Each bit represents one signal line. 0 = line is an input to the FPGA, 1 = line is an output driven by the FPGA.
|
||||
// Each bit represents one signal line. 0 = line is an input to the FPGA,
|
||||
// 1 = line is an output driven by the FPGA.
|
||||
// </info>
|
||||
// <bitfield name="DIO_DIRECTION_A" range="0..11" initialvalue="0"/>
|
||||
// <bitfield name="DIO_DIRECTION_B" range="16..27" initialvalue="0"/>
|
||||
// </register>
|
||||
// <register name="DIO_INPUT_REGISTER" offset="0x08" size="32" writable="false">
|
||||
// <register name="DIO_INPUT_REGISTER" offset="0x08" typename="DIO_CONTROL_REG" writable="false">
|
||||
// <info>
|
||||
// Status of each bit at the FPGA input.
|
||||
// </info>
|
||||
// <bitfield name="DIO_INPUT_A" range="0..11"/>
|
||||
// <bitfield name="DIO_INPUT_B" range="16..27"/>
|
||||
// </register>
|
||||
// <register name="DIO_OUTPUT_REGISTER" offset="0x0C" size="32">
|
||||
// <register name="DIO_OUTPUT_REGISTER" offset="0x0C" typename="DIO_CONTROL_REG">
|
||||
// <info>
|
||||
// Controls the values on each DIO signal line in case the line master is set to PS in @.DIO_MASTER_REGISTER.
|
||||
// Controls the values on each DIO signal line in case the line master is
|
||||
// set to PS in @.DIO_MASTER_REGISTER.
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="DIO_SOURCE_REGISTER" offset="0x10" typename="DIO_CONTROL_REG">
|
||||
// <info>
|
||||
// Controls whether the DIO lines reflect the state of @.DIO_MASTER_REGISTER
|
||||
// or the radio blocks. 0 = @.DIO_MASTER_REGISTER,
|
||||
// 1 = Radio block output(@.DIO_OVERRIDE)
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="RADIO_SOURCE_REGISTER" offset="0x14" typename="DIO_CONTROL_REG">
|
||||
// <info>
|
||||
// Controls which radio block to use the ATR state from to determine the
|
||||
// state of the DIO lines.
|
||||
// 0 = Radio#0
|
||||
// 1 = Radio#1
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="INTERFACE_DIO_SELECT" offset="0x18" typename="DIO_CONTROL_REG">
|
||||
// <info>
|
||||
// Controls which of the two available digital interfaces controls the DIO lines.
|
||||
// 0 = Digital interface from Radio#0,
|
||||
// 1 = Digital Interface from Radio#1.
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="DIO_OVERRIDE" offset="0x1C" typename="DIO_CONTROL_REG">
|
||||
// <info>
|
||||
// Controls whether the radio input to the @.DIO_SOURCE_REGISTER mux
|
||||
// connects to the ATR control or a Digital interface block. The output
|
||||
// of the mux controlled by this bit goes to @.DIO_SOURCE_REGISTER.
|
||||
// 0 = Drive the ATR state(@.RADIO_SOURCE_REGISTER), 1 = Drive
|
||||
// Digital interface block(Output of @.INTERFACE_DIO_SELECT).
|
||||
// </info>
|
||||
// </register>
|
||||
// <register name="SW_DIO_CONTROL" offset="0x20" typename="DIO_CONTROL_REG">
|
||||
// <info>
|
||||
// Controls which source is forwarded to the @.DIO_MASTER_REGISTER mux.
|
||||
// This configuration is applied independently for each DIO line.
|
||||
// 0 = MPM Ctrlport endpoint, 1 = PS Netlist DIO signal.
|
||||
// </info>
|
||||
// <bitfield name="DIO_OUTPUT_A" range="0..11" initialvalue="0"/>
|
||||
// <bitfield name="DIO_OUTPUT_B" range="16..27" initialvalue="0"/>
|
||||
// </register>
|
||||
// </group>
|
||||
//</regmap>
|
||||
|
||||
Reference in New Issue
Block a user